// ==UserScript==
// @name         115优化大师
// @author       zxf10608
// @version      6.7.01
// @icon      	 https://cdn.jsdelivr.net/gh/zxf10608/JavaScript/icon/115logo.ico
// @namespace    https://greasyfork.org/zh-CN/scripts/408466
// @description  优化115网盘使用体验：一键离线下载、批量离线、调用Dplayer或Potplayer播放视频、文件快捷下载、批量下载、磁力转换种子等。
// @require      https://cdn.jsdelivr.net/npm/jquery@3.6.4/dist/jquery.min.js
// @require      https://greasyfork.org/scripts/398240-gm-config-zh-cn/code/GM_config_zh-CN.js
// @require      https://greasyfork.org/scripts/412267-base64-v1-0/code/base64_v10.js
// @require      https://cdn.jsdelivr.net/npm/hls.js@1.4.10/dist/hls.min.js
// @require      https://cdn.jsdelivr.net/npm/toastr@2.1.4/toastr.min.js
// @resource     toastrCss   https://cdn.jsdelivr.net/npm/toastr@2.1.4/build/toastr.min.css
// @require      https://cdn.jsdelivr.net/npm/dplayer@1.26.0/dist/DPlayer.min.js
// @resource     dplayerCss  https://cdn.jsdelivr.net/npm/dplayer/dist/DPlayer.min.css
// @include      *
// @include      http*://*.115.com/*
// @exclude      http*://*.115.com/bridge*
// @exclude      http*://*.115.com/*/static*
// @exclude      http*://*.baidu.com/*
// @exclude      http*://*.iqiyi.com/*
// @exclude      http*://*.qq.com/*
// @exclude      http*://*.youku.com/*
// @exclude      http*://*.bilibili.com/
// @exclude      http*://*.pptv.com/*
// @exclude      http*://*.fun.tv/*
// @exclude      http*://*.sohu.com/*
// @exclude      http*://*.le.com/*
// @exclude      http*://*.tudou.com/*
// @exclude      http*://*.bilibili.com/*
// @exclude      http*://music.163.com/*
// @exclude      http*://github.com/*
// @exclude      http*://gitee.com/*
// @exclude      http*://btcache.me/*
// @exclude      http*://*.jd.com/*
// @exclude      http*://*.taobao.com/*
// @exclude      http*://*.tmall.com/*
// @exclude      http*://*.vip.com/*
// @exclude      http*://*.pinduoduo.com/*

// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addStyle
// @grant        GM_download
// @grant        GM_openInTab
// @grant        GM_setClipboard
// @grant        GM_getResourceText
// @grant        GM_xmlhttpRequest
// @grant        GM_registerMenuCommand
// @connect      115.com
// @connect      *
// @grant        unsafeWindow
// @grant        window.open
// @grant        window.close
// @run-at       document-start
// @compatible   chrome
// @license      GPL License
// ==/UserScript==

(function() {

    'use strict';
    var newVersion = 'v6.7';

    if ( typeof GM_config == 'undefined') {
        alert('115优化大师：\n网络异常，相关库文件加载失败，脚本无法使用，请刷新网页重新加载！');
        return;
    } else {
        console.log('115优化大师：相关库文件加载成功！');
    };

    function config(){
        var windowCss = '#Cfg .nav-tabs {margin: 20 2} #Cfg .config_var textarea{width: 310px; height: 50px;} #Cfg .inline {padding-bottom:0px;} #Cfg .config_header a:hover {color:#1e90ff;} #Cfg .config_var {margin-left: 10%;margin-right: 10%;} #Cfg input[type="checkbox"] {margin: 3px 3px 3px 0px;} #Cfg input[type="text"] {width: 53px;} #Cfg {background-color: lightblue;} #Cfg .reset_holder {float: left; position: relative; bottom: -1em;} #Cfg .saveclose_buttons {margin: .7em;} #Cfg .section_desc {font-size: 10pt;}';

        GM_registerMenuCommand('设置', opencfg);
        function opencfg(){
            GM_config.open();
        };

        GM_config.init(
            {
                id: 'Cfg',
                title: GM_config.create('a', {
                    href: 'https://greasyfork.org/zh-CN/scripts/408466',
                    target: '_blank',
                    className: 'setTitle',
                    textContent: '115优化大师',
                    title: '作者：zxf10608 版本：'+newVersion+' 点击访问主页'
                }),
                isTabs: true,
                skin: 'tab',
                css: windowCss,
                frameStyle:
                    {
                        height: '550px',
                        width: '445px',
                        zIndex:'2147483648',
                    },
                fields:
                    {
                        file_Down:
                            {
                                section: ['文件管理', '提高文件管理效率'],
                                label: '启用文件快捷下载',
                                labelPos: 'right',
                                type: 'checkbox',
                                default: true,
                            },
                        down_batch:
                            {
                                label: '启用文件批量下载',
                                labelPos: 'right',
                                type: 'checkbox',
                                default: true,
                            },
                        down_five:
                            {
                                label: '选中5个内直接下载',
                                labelPos: 'right',
                                type: 'checkbox',
                                default: true,
                            },
                        show_sha:
                            {
                                label: '下载后保存校验码',
                                labelPos: 'right',
                                type: 'checkbox',
                                default: false,
                            },
                        down_Agreement:
                            {
                                label: '启用https下载协议',
                                labelPos: 'right',
                                type: 'checkbox',
                                default: false,
                            },
                        extract_file:
                            {
                                label: '启用文件批量提取',
                                labelPos: 'right',
                                type: 'checkbox',
                                default: true,
                                line: 'start',
                            },
                        extract_save:
                            {
                                label: '提取模式',
                                labelPos: 'left',
                                type: 'select',
                                'options': ['复制','移动'],
                                default: '复制',
                            },
                        extract_type:
                            {
                                label: '提取类型',
                                labelPos: 'left',
                                type: 'select',
                                'options': ['全部','仅文件','视频','音乐','图片','文档'],
                                default: '仅文件',
                                line: 'end',
                            },
                        reminder1:
                            {
                                label: '温馨提示',
                                labelPos: 'right',
                                type: 'button',
                                click: function(){
                                    alert('1、批量下载文件少于5个，直接浏览器下载。大于5个，所有下载地址将复制到剪切板；\n2、“https”下载协议仅在“http”访问不可用时启用，一般情况不建议开启，否则可能造成下载失败。');
                                }
                            },
                        offline_Down:
                            {
                                section: ['离线升级', '升级离线下载功能'],
                                label: '启用一键离线下载',
                                labelPos: 'right',
                                type: 'checkbox',
                                default: true,
                            },
                        offline_result:
                            {
                                label: '任务添加后显示离线结果',
                                labelPos: 'right',
                                type: 'checkbox',
                                default: true,
                            },
                        open_List:
                            {
                                label: '离线后自动打开任务列表',
                                labelPos: 'right',
                                type: 'checkbox',
                                default: false,
                            },
                        open_search:
                            {
                                label: '离线成功后开启视频搜索',
                                labelPos: 'right',
                                type: 'checkbox',
                                default: true,
                                line: 'start',
                            },
                        search_result:
                            {
                                label: '显示视频搜索结果',
                                labelPos: 'right',
                                type: 'checkbox',
                                default: true,
                            },
                        open_Popup:
                            {
                                label: '搜到视频自动播放',
                                labelPos: 'right',
                                type: 'checkbox',
                                default: false,
                                line: 'end',
                            },
                        fuzzy_find:
                            {
                                label: '启用下载地址模糊匹配',
                                labelPos: 'right',
                                type: 'checkbox',
                                default: false,
                            },
                        diy_folder:
                            {
                                label: '自定义离线下载文件夹',
                                labelPos: 'right',
                                type: 'checkbox',
                                default: false,
                                line: 'start',
                            },
                        save_folder:
                            {
                                label: '设置文件夹',
                                labelPos: 'right',
                                type: 'button',
                                line: 'end',
                                click: function(){
                                    setFolder();
                                }
                            },
                        reminder2:
                            {
                                label: '温馨提示',
                                labelPos: 'right',
                                type: 'button',
                                click: function(){
                                    alert('1、显示离线下载结果有10s延时，用于服务器响应时间。\n2、为避免通知弹窗过多，最多只显示3个视频搜索结果，更多请自行到115查看。\n3、“启用下载地址模糊匹配”后，能根据哈希值或纯文本模糊匹配磁力链接和迅雷专用链，如在磁力搜索引擎、资源网等有奇效，但在某些网页有一定几率误识别，请谨慎开启。');
                                }
                            },
                        player:
                            {
                                section: ['播放优化', '调用第三方播放器，优化播放体验'],
                                label: '默认播放器',
                                labelPos: 'left',
                                type: 'select',
                                options: ['Dplayer','官方HTML5','本地播放','苹果IINA','其他'],
                                default: 'Dplayer',
                            },
                        play_Quality:
                            {
                                label: '默认播放清晰度',
                                labelPos: 'left',
                                type: 'select',
                                'options': ['最高','次高','最低'],
                                default: '最高',
                            },
                        skip_titles:
                            {
                                label: '跳过片头秒数',
                                type: 'unsigned int',
                                default: '0',
                            },
                        skip_credits:
                            {
                                label: '跳过片尾秒数',
                                type: 'unsigned int',
                                default: '0',
                            },
                        local_player:
                            {
                                label: '自定义本地播放接口',
                                labelPos: 'right',
                                type: 'button',
                                click: function(){
                                    setLocalplayer();
                                }
                            },
                        online_List:
                            {
                                label: '开启云端记忆播放',
                                labelPos: 'right',
                                type: 'checkbox',
                                default: true,
                            },
                        M3U_list:
                            {
                                label: '启用生成播放列表',
                                labelPos: 'right',
                                type: 'checkbox',
                                default: true,
                            },
                        Tab_ing:
                            {
                                label: '播放器跟随页面变化',
                                labelPos: 'right',
                                type: 'checkbox',
                                default: false,
                            },
                        web_fullscreen:
                            {
                                label: '官方HTML5自动网页全屏',
                                labelPos: 'right',
                                type: 'checkbox',
                                default: true,
                            },
                        hide_play:
                            {
                                label: '隐藏第三方播放器悬浮按钮',
                                labelPos: 'right',
                                type: 'checkbox',
                                default: false,
                            },
                        reminder3:
                            {
                                label: '温馨提示',
                                labelPos: 'right',
                                type: 'button',
                                click: function(){
                                    alert('1、除第一、第二项外，其他仅在启用Dplayer时有效。\n2、开启云端记忆播放，播放记录将自动上传至云端（115服务器），下次播放自动恢复上一次进度。\n3、播放界面右键可显示更多菜单，谨慎使用“删除”操作。；\n4、本地播放器(Potplayer等)需手动关联M3U文件(.m3u)，方可正常打开M3U播放列表。播放列表有效期几小时，失效请重新生成；\n5、播放器跟随页面变化，即页面后台则暂停,页面前台则播放，支持Dplayer和官方HTML5。\n6、关于播放器调用说明：\n 单击文件名：默认播放器；\n 双击除文件名外：官方HTML5；\n 单击“Dp播放”：Dplayer；\n 单击“Pot播放”：Potplayer；\n 非115页面：默认播放器。');
                                }
                            },
                        hide_qrcodeLogin:
                            {
                                section: ['更多设置', '优化浏览体验'],
                                label: '隐藏二维码登录',
                                labelPos: 'right',
                                type: 'checkbox',
                                default: false,
                            },
                        hide_officeLogin:
                            {
                                label: '隐藏115组织登录',
                                labelPos: 'right',
                                type: 'checkbox',
                                default: false,
                            },
                        hide_sidebar:
                            {
                                label: '隐藏网盘侧边栏',
                                labelPos: 'right',
                                type: 'checkbox',
                                default: false,
                            },
                        show_Alidity:
                            {
                                label: '显示上次登录时间',
                                labelPos: 'right',
                                type: 'checkbox',
                                default: false,
                            },
                        show_Star:
                            {
                                label: '网盘顶部增加星标按钮',
                                labelPos: 'right',
                                type: 'checkbox',
                                default: false,
                            },
                        show_Offline:
                            {
                                label: '网盘顶部增加云下载按钮',
                                labelPos: 'right',
                                type: 'checkbox',
                                default: true,
                            },
                        show_Task:
                            {
                                label: '网盘顶部增加链接任务按钮',
                                labelPos: 'right',
                                type: 'checkbox',
                                default: true,
                            },
                        show_Update:
                            {
                                label: '更新后弹出更新日志',
                                labelPos: 'right',
                                type: 'checkbox',
                                default: false,
                            },
                        toastr:
                            {
                                label: '通知弹出位置',
                                labelPos: 'left',
                                type: 'select',
                                'options': ['左上', '右上', '中上','全铺'],
                                default: '右上',
                            },
                        http_ua:
                            {
                                label: '数据请求UA标识（非必要勿改）',
                                type: 'textarea',
                                default: ''
                            },


                    },

                events:
                    {
                        save: function(){
                            GM_config.close();
                            location.reload();
                        }
                    },
            });
    };
    config();



    var G = GM_config;
    var localHref = window.location.href;
    var show_result = G.get('offline_result');
    var down_reg = /^(magnet|thunder|ftp|ed2k):/i;
    var player_api = GM_getValue('localplayer') || 'potplayer://';
    var UA = G.get('http_ua')!=''? G.get('http_ua'):navigator.userAgent;
    var sign_url = 'http://115.com/?ct=offline&ac=space';
    var task_del = 'https://115.com/web/lixian/?ct=lixian&ac=task_del';
    var add_url = 'http://115.com/web/lixian/?ct=lixian&ac=add_task_url';
    var add_urls = 'http://115.com/web/lixian/?ct=lixian&ac=add_task_urls';
    var add_bt = 'http://115.com/web/lixian/?ct=lixian&ac=add_task_bt';
    var lists_url = 'http://115.com/web/lixian/?ct=lixian&ac=task_lists';
    var a_list= `<br><a target="_blank" class="openList" href="javascript:void(0);" style="color:blue;" title="打开离线链接任务列表">打开任务</a>`;
    console.log('115脚本UA：'+UA);

    function notice(){
        GM_addStyle(GM_getResourceText('toastrCss'));
        if(G.get('toastr')=='全铺'|| localHref.indexOf('https://captchaapi.115.com') != -1) {
            GM_addStyle('.toast{font-size:15px!important;} .toast-title{font-size:16px!important;text-align:center}');
        }else{
            GM_addStyle('.toast{font-size:15px!important;width:360px!important;} .toast-title{font-size:16px!important;text-align:center}');
        };
        var place = {'左上':'toast-top-left','右上':'toast-top-right','中上':'toast-top-center'}[G.get('toastr')] || 'toast-top-full-width';
        toastr.options = {
            "closeButton": true,
            "debug": false,
            "progressBar": true,
            "timeOut": 8000,
            "extendedTimeOut": 8000,
            "positionClass": place,
            "allowHtml": true,
            "newestOnTop" : false,
        };
    };
    notice();

    function AjaxCall(href,callback) {
        GM_xmlhttpRequest({
            method: "GET",
            url: href,
            headers: {
                "User-Agent": UA,
                Origin: "https://115.com",
            },
            onload: function(data,status) {
                if(data.readyState==4 && data.status==200){
                    var htmlTxt = data.responseText;
                    callback(null,htmlTxt);
                };
            },
            onerror: function (error) {
                callback(error);
            },
            ontimeout: function (error) {
                callback(error);
            },
        });
    };

    function setFolder(){
        var old_cid = GM_getValue('offlineFolder') || '';
        var new_cid = prompt('请输入离线下载保存文件夹的cid值：\n   ※ 获取cid值方法：打开需要保存到的网盘文件夹，复制地址栏中"cid="后面的一串数字，以"&"截止，如https://115.com/?cid=012345678912345678&...，cid值则为 012345678912345678。该项不填或填无效值则保存至默认文件夹（云下载）。※'
            ,old_cid);
        if (/^(\d{17,19}|0)$/.test(new_cid)){
            GM_setValue('offlineFolder',new_cid);
            alert('设置成功，现cid值为：\n'+new_cid);
        }else if(new_cid==''){
            GM_setValue('offlineFolder','');
            alert('未输入cid值，保存至默认文件夹（云下载）。');
        }else if(new_cid==null){
            console.log('已点击取消');
        }else{
            alert('设置失败，cid值无效，请重新输入！\n（该值除根目录为 0 外，其他文件夹均为17至19位纯数字）');
            setFolder();
        };

    };

    function setLocalplayer(){
        var old_api = GM_getValue('localplayer') || 'potplayer://';
        var new_api = prompt('请输入本地播放接口的api值：\n   ※ 默认值（potplayer://）为Potplayer播放器调用接口，可根据实际情况更改为其他第三方本地播放器接口，需自行注册关联协议。※'
            ,old_api);
        if (/^\w+:\/\/$/.test(new_api)){
            GM_setValue('localplayer',new_api);
            alert('设置成功，现api值为：\n'+new_api);
        }else if(new_api==''){
            GM_setValue('localplayer','potplayer://');
            alert('未输入api值，设为默认值（potplayer://）。');
        }else if(new_api==null){
            console.log('已点击取消');
        }else{
            alert('设置失败，api值无效，请重新输入！');
            setLocalplayer();
        };
    };

    function download(key,num){
        return new Promise(function(resolve,reject){
            var batch= typeof num != 'undefined'? true:false;
            var href = `https://webapi.115.com/files/download?pickcode=${key.pc}&_=${new Date().getTime()}`;
            AjaxCall(href,function(error,htmlTxt){
                if(error){
                    console.log('网络错误，获取文件地址失败！');
                    resolve([false,error]);
                    return;
                };
                var json = JSON.parse(htmlTxt);

                if(json.state){
                    var link=json.file_url;
                    if (G.get('down_Agreement')){
                        link=link.replace(/^http/,'https');
                    };
                    batch? resolve([link,key.n,num,key.sha]):resolve([link]);
                }else{
                    originLink(key.pc,key.fid,'115origin').then(function(origin){
                        if(origin[0]){
                            var link=origin[0];
                            if (G.get('down_Agreement')){
                                link=link.replace(/^http/,'https');
                            };
                            batch? resolve([link,key.n,num,key.sha]):resolve([link]);
                        }else{
                            batch? resolve([false,key.n,num,origin[1]]):resolve([false,origin[1]]);
                        };
                    });
                };
            });
        });
    };

    function originLink(pid,fid,type,name,i){
        return new Promise(function(resolve,reject){
            if (type !='115origin' && (G.get('play_Quality') !='原码' || ((G.get('player') == 'Dplayer' && type == '115play') || type == 'Dp'))){

                resolve([false,'ignore']);
                return;
            };
            var href = 'http://proapi.115.com/app/chrome/down?method=get_file_url&pickcode='+pid;
            AjaxCall(href,function(error,htmlTxt){
                if(error){
                    console.log('网络错误，获取文件地址失败！');
                    resolve([false,error]);
                    return;
                };
                var json = JSON.parse(htmlTxt);
                if(json.state){
                    var link = json.data[fid].url.url;
                    name? resolve([link,name,i]):resolve([link]);
                }else{
                    if(name){
                        resolve([false,name,i,json.msg]);
                    }else{
                        resolve([false,json.msg]);
                    };
                };
            });
        });
    };
    function getHistory(pid){
        return new Promise(function(resolve,reject){
            var href = 'https://webapi.115.com/files/history?pick_code='+pid+'&fetch=one&category=1';
            AjaxCall(href,function(error,htmlTxt){
                var time = 0;
                if(error){
                    console.log('网络错误，获取播放记录失败！');
                    resolve(time);
                };
                var json = JSON.parse(htmlTxt);
                if(json.state){
                    if(!json.data.watch_end){
                        time = json.data.time;
                    };
                };
                resolve(time);
            });
        });
    };

    function getM3u8(video,type){
        return new Promise(function(resolve,reject){
            var herfLink = 'https://115.com/api/video/m3u8/'+video.pid+'.m3u8';
            AjaxCall(herfLink,function(error,htmlTxt){
                if (typeof htmlTxt == 'undefined') {
                    transcoding(video,type);
                    resolve([false,video]);
                    return;
                };
                var dataList = htmlTxt.split('\n');
                var m3u8 = [];
                var temp = '"YH"|原画|"BD"|4K|"UD"|蓝光|"HD"|超清|"SD"|高清|"3G"|标清';
                var txt = temp.split('|');
                for (var i=0; i<6; i++){
                    dataList.forEach(function (e,j,arr) {
                        if (e.indexOf(txt[i*2])!= -1) {
                            m3u8.push({name: txt[i*2+1], url: arr[j+1].replace(/\r/g,''), type:'hls'});
                        };
                    });
                };

                if (m3u8.length ==1 || G.get('play_Quality') =='最高' || G.get('play_Quality') =='原码'){
                    var num = 0;
                }else if(m3u8.length >1 && G.get('play_Quality') =='次高'){
                    var num = 1;
                }else{
                    var num = m3u8.length - 1;
                };
                video['quality'] = num;
                resolve([m3u8,video,num]);
            });
        });
    };

    function switchPlayer(origin,type,m3u8,n){
        if(origin[0]){
            var link=origin[0];
            var name=origin[1];
            var definition='原码';
        }else if(m3u8){
            var link= m3u8.url;
            var name=n;
            var definition=m3u8.name;
        }else{
            toastr.error('未知错误，请稍后再试。','播放失败!');;
            return;
        };
        var txt='';
        if((G.get('player') == 'Dplayer' && /^115/.test(type)) || type == 'Dp'){
            var Dp=true;
            if(origin[0]) var txt='Dplayer不支持原码播放，';
        }else{
            var Dp=false;
        };

        if ((G.get('player') == '本地播放' && /^115/.test(type)) || type == 'Local'){
            if(/smplayer|potplayer2/.test(player_api)){
                var info=`${player_api}|${link}|${UA}|${name}`;
            }else{
                var info= player_api+link;
            };
            window.location.href = info;
        }else if((G.get('player') == '苹果IINA' && /^115/.test(type))){
            window.location.href = 'iina://weblink?url='+link;
        }else if(m3u8 && Dp){
            if(link.match(/http:\/\/videotsgo\.115\.com/) != null){
                GM_openInTab('http://videotsgo.115.com',false);
                return;
            };
            GM_openInTab('http://115.com/web/lixian/',false);
        }else{
            GM_setClipboard(link);
            toastr.success(txt+'请使用其他播放器打开该地址。',`<span style="color:purple;">${definition}</span> 地址复制成功！`,{timeOut:8000});
        };
    };

    function palyData(video,type){
        if ((G.get('player') =='官方HTML5' && type == '115play') || type == 'dblclick'){

            var link = 'https://115.com/?ct=play&ac=location&pickcode='+video.pid+'&hls=1';
            GM_openInTab(link,false);
            return;
        };

        originLink(video.pid,video.fid,type,video.name).then(function(origin){
            if(origin[0]){
                switchPlayer(origin,type);
                return;
            }else if(origin[1]!='ignore'){
                toastr.warning('获取视频原码地址失败，将播放转码最高清晰度。','播放原码失败!',{timeOut:6000});
            };

            getM3u8(video).then(function(data){
                if(!data[0]){
                    toastr.warning('未获取播放地址。','播放失败！');
                    return;
                };
                GM_setValue('videoInfo',data[1]);
                GM_setValue('m3u8List',data[0]);
                switchPlayer(origin,type,data[0][data[2]],data[1].name);
            });
        }, function(error) {
            toastr.error('服务器繁忙，请稍后再试。','操作异常!');
            console.log(error);
        });
    };

    function transcoding(video,type){

        var href = 'http://transcode.115.com/api/1.0/web/1.0/trans_code/check_transcode_job?sha1='+video.sha+'&priority=100';
        console.log('转码进度地址:'+href);
        AjaxCall(href,function(error,htmlTxt){
            var json = JSON.parse(htmlTxt);
            if(json.status == 1 || json.status == 3){
                var num = json.count;
                var time = tranTime(json.time).replace(/分.*/,'分');

                var txt = `等待转码排名：第${num}名，耗时：约${time}，请稍后再试。`;
            }else if(json.status == 127){
                var txt = '未获取到转码进度，请稍后再试或选择原码播放。';
                console.log('查询转码进度失败');
            };
            var videoTxt = JSON.stringify(video);
            var h1 = `<br><a target="_blank" class="transcode_show" data=${videoTxt} href="javascript:void(0);" style="cursor:pointer;color:blue;" title="打开转码进度详情页">转码详情</a>`;
            var h2 = '';
            var h3 = '';
            if(type==2){
                return;
            }else if(type==1){
                var title ='加速转码成功！';
            }else if(type){
                var title ='加速转码失败！';
                var txt = type;
            }else{
                var title ='播放失败，视频未转码！';
                h2 = `&nbsp;&nbsp;<a target="_blank" class="transcode_fast" data=${videoTxt} href="javascript:void(0);" style="cursor:pointer;color:blue;" title="加速转码进度">加速转码</a>`;
            };

            toastr.warning(txt+h1+h2+h3,title,{timeOut:10000});
        });
    };

    function transcod_fast(video){
        var push_url = 'https://115.com/?ct=play&ac=push';
        var key = `op=vip_push&pickcode=${video.pid}&sha1=${video.sha}`;
        offline.getData(push_url,key).then(function(json){


            if(json.state){
                var type= 1;
                transcoding(video,type);
                console.log('加速转码成功！');
                return;
            }else{
                var type= json.msg;
                transcoding(video,type);
                console.log('加速转码失败！');
            };
        });
    };

    function folderList(cid,name,type,sort,end){
        return new Promise(function(resolve,reject){
            var e = end? end:'';
            var s = sort? sort:'file_name';
            var key = {
                aid: 1,
                cid: cid,
                offset: 0,
                limit: 100,
                show_dir: 1,
                qid: 0,
                type: type,
                format: 'json',
                r_all: 1,
                o: sort,
                suffix: e,
                asc: 1,
                cur: 1,
                natsort: 1
            };

            var href = 'https://aps.115.com/natsort/files.php?'+$.param(key);

            var tp = {'4':'视频','3':'音乐','2':'图片','1':'文档'}[type] || '文件';
            AjaxCall(href,function(error,htmlTxt){
                var json = JSON.parse(htmlTxt);
                console.log('文件夹列表信息:');
                console.log(json);
                if(json.state){
                    if(json.count==0){
                        toastr.warning(`文件夹：<span style="color:purple;">${name}</span> 未搜索到${tp}。`,'操作失败！');
                        resolve([false,json]);
                    }else if(json.count>99){
                        toastr.warning('所属文件数量大于 <span style="color:red;">100</span> 个。','操作无效！');
                        resolve([false,json]);
                    }else{
                        resolve([json,name]);
                    };
                }else{
                    toastr.warning(json.error,'文件夹检索失败!');
                    resolve([false,json]);
                };
            });
        });
    };

    function batchList(key,down){

        var m3u8ed=false;
        var end=false;
        var one=(key.count==1&&!down)? true:false;
        let urls = [];
        for(let i=0;i<key.count;i++){
            var el=key.data[i];
            if(down){
                download(el,i).then(function(data){
                    if(data[0]){
                        urls.push({num:data[2],href:data[0],name:data[1],sha:data[3]});
                    }else{
                        toastr.warning(data[1]+' 获取下载地址失败!');
                        console.log(data[1]+'获取地址失败：'+data[3]);
                    };
                });
            }else{
                var video={pid:el.pc,name:el.n,n1:i};
                getM3u8(video,2).then(function(data){
                    if(!data[0]){
                        toastr.warning(data[1].name+' 未获取到转码播放地址。');
                    }else{
                        var m3u8=data[0];
                        if(one){
                            for(var j=0;j<m3u8.length;j++){
                                urls.push({num:j+1,name:data[1].name,txt:`#EXTINF:-1 ,${data[1].name} ${m3u8[j].name}\r\n${m3u8[j].url}\r\n`});
                            };
                        }else{
                            urls.push({num:data[1].n1,name:data[1].name,txt:`#EXTINF:-1 ,${data[1].name} ${m3u8[data[2]].name}\r\n${m3u8[data[2]].url}\r\n`});
                        };
                    };
                    m3u8ed=true;
                });
            };
        };

        var time5 = setInterval(function(){
            if(one){
                if(m3u8ed){
                    end=true;
                };
            }else if(urls.length==key.count){
                end=true;
            };
            if(end){
                urls.sort(function(a, b){
                    return a.num - b.num
                });
                if(down){
                    var links=[];
                    var m5ds='文件校验码(sha1):\r\n';
                    for(var k=0;k<urls.length;k++){
                        links.push(urls[k].href);
                        m5ds += `${urls[k].name}|${urls[k].sha}\r\n`;
                        if(key.count<=5 && G.get('down_five')){
                            (function(a){
                                setTimeout(function() {
                                    GM_openInTab(urls[a].href);
                                }, a*1000);
                            })(k);
                            if(k==4) break;
                        };
                    };
                    setTimeout(function(){
                        if(G.get('show_sha')){
                            GM_download({url:'data:text/plain;charset=utf-8,'+encodeURIComponent(m5ds),name:'校验码'});
                            toastr.success('校验码文档已下载！');
                        };
                    }, 1000);

                    if(key.count<=5 && G.get('down_five')){
                        clearInterval(time5);
                        return;
                    };
                    GM_setClipboard(links.join('\r\n'));
                    toastr.success(urls.length+'个下载地址复制成功！');
                    clearInterval(time5);
                    return;
                };

                var hrefs = `#EXTM3U\r\n#EXTVLCOPT:http-user-agent=${UA}\r\n`;
                for(var k=0;k<urls.length;k++){
                    hrefs += urls[k].txt;
                };

                var t1=one? '':'等';
                var t2=one? '清晰度':'视频';
                var title=urls[0].name.replace(/\.\w{2,4}$/,'').replace(/\./g,'_')+t1;
                var link1='data:audio/mpegurl;charset=utf-8,'+encodeURIComponent(hrefs);
                GM_download({url:link1,name:title});
                toastr.success(`共 ${urls.length} 个${t2}，请用本地播放器打开，失效请重新生成。`,'播放列表已下载');
                clearInterval(time5);
            };
        }, 100);
        setTimeout(function(){
            if(urls.length!=key.count){
                if(urls.length!=0){
                    if(!one){
                        toastr.warning('部分文件地址获取失败。','批量操作异常!');
                    };
                    end=true;
                }else{
                    toastr.warning('所选文件大小均超出115M上限，无法获取文件地址。','批量操作失败!');
                    clearInterval(time5);
                };
            };
        },7000);
    };

    function extractList(p_id,info){
        var num = [];
        var fids = [];
        var m = G.get('extract_save')=='复制'? 'copy':'move';
        var t = {'全部':'0','仅文件':'99','视频':'4','音乐':'3','图片':'2','文档':'1'}[G.get('extract_type')];

        for(let i=0;i<info.length;i++){
            folderList(info[i].cid,info[i].n,t).then(function(obj){
                if(obj[0]){
                    num.push(obj[0].count);
                    for(var j=0;j<obj[0].count;j++){
                        var fid=obj[0].data[j].fid || '';
                        if (fid!=''){
                            fids.push(fid);
                        }else{
                            fids.push(obj[0].data[j].cid);
                        };
                    };
                }else{
                    num.push('0');
                };
            });
        };

        var end=false;
        var time6 = setInterval(function(){
            if(info.length==num.length || end){
                var h=eval(num.join('+'));
                if(h>200){
                    toastr.warning('所选文件总数大于 <span style="color:red;">200</span> 个，请分批操作。','操作无效！');
                    return;
                };
                var link ='https://webapi.115.com/files/' + m;
                var key = {pid:p_id};
                for(var k=0; k<fids.length; k++){
                    key['fid['+k+']']=fids[k];
                };
                offline.getData(link,$.param(key)).then(function(json){
                    console.log('批量提取结果:');
                    console.log(json);
                    if(json.state) {
                        toastr.success(h+' 个文件批量提取成功！');
                        setTimeout(function(){
                            window.location.reload();
                        },3000);

                    }else{
                        toastr.warning(json.error,'批量提取失败!');
                    };
                });
                clearInterval(time6);
            };
        }, 100);

        setTimeout(function(){
            if(info.length!=num.length){
                if(num.length!=0){
                    toastr.warning('部分文件提取失败。','批量操作异常!');
                    end=true;
                }else{
                    toastr.warning('所有文件夹提取操作均失败','批量提取错误!');
                    clearInterval(time6);
                };
            };
        },8000);
    };

    function change(number){
        var size = "";
        if(number < 1024 * 1024 * 1024){
            size = (number/(1024 * 1024)).toFixed(2) + "MB";
        }else{
            size = (number/(1024 * 1024 * 1024)).toFixed(2) + "GB";
        };
        var sizeStr = size + "";
        var index = sizeStr.indexOf(".");
        var dou = sizeStr.substr(index + 1 ,2)
        if(dou == "00"){
            return sizeStr.substring(0, index) + sizeStr.substr(index + 3, 2)
        };
        return size;
    };

    function name2(txt){
        var newName=txt.replace(/\.(?!\w{2,4}$)/g,'_')
            .replace(/\s/g,'&nbsp;');
        return newName;
    };
    function tranTime(num){
        var showTime = '';
        if (num > 3600) {showTime += ' '+parseInt(num/3600)+' 小时'; num = num%3600;}
        if (num > 60) {showTime += ' '+parseInt(num/60)+' 分'; num = num%60;}
        return showTime += ' '+parseInt(num)+' 秒';
    };

    function enterPiP(videoEl){
        if(document.pictureInPictureEnabled && !videoEl.disablePictureInPicture) {
            if (!document.pictureInPictureElement) {
                videoEl.requestPictureInPicture();
            }else{
                document.exitPictureInPicture();
            };
        }else{
            alert('浏览器不支持或已关闭画中画功能！');
        };
    };

    function clickOne(el,t){
        var time=t? t:5000;
        if (el.attr('clicked') == 1){
            console.log('5s内不可点击该按钮');
            return false;
        }else{
            el.attr('clicked',1);
            el.css('opacity','0.2');
            setTimeout(function(){
                el.attr('clicked',0);
                el.css('opacity','0.7');

            },time);
            return true;
        };
    };

    function resultMark(el,type){
        if(el.length==0 || !show_result) return;

        var urls=[];
        var color={1:'#00CCFF',2:'#DA70D6',3:'#AEDD81',4:'#EB7347'}[type];
        for(var i=0;i<el.length;i++){
            urls.push(el[i].url);
            $('.115offline').each(function(){
                var link=$(this).data('href');
                var $al=$(this).prev();
                var m=$al.attr('marked');
                if ((el[i].url == link || el[i].url == decodeURIComponent(link)) && m != 3){
                    $al.attr('marked',type).css('background-color',color);
                    $al.find('[style]').removeAttr('style');
                    return false;
                };
            });
        };
        return urls;
    };

    function repeat(link){
        var result=false;
        var A=link.slice(0,60);
        if($('.115offline').length==0) return result;
        $('.115offline').each(function(){
            var B=$(this).data('href').slice(0,60);
            if(A.toLowerCase() == B.toLowerCase()){
                result=true;
                return false;
            };
        });
        return result;
    };

    function searchTask(json,link){
        var dataEl = false;
        for(var i=0;i<json.tasks.length;i++){
            if (json.tasks[i].url == link || json.tasks[i].url == decodeURIComponent(link)){
                dataEl = json.tasks[i];
                break;
            };
        };
        return dataEl;
    };

    function verify(){
        var time = new Date().getTime();
        var w=335;
        var h=500;
        var t = (window.screen.availHeight-h)/2;
        var l = (window.screen.availWidth-w)/2;
        var link = 'https://captchaapi.115.com/?ac=security_code&type=web&cb=Close911_'+time;
        var a = confirm('立即打开验证账号弹窗？');
        if (a){
            var blocked = false;
            try{
                var wroxWin=window.open(link,'请验证账号','height='+h+',width='+w+',top='+t+',left='+l+',toolbar=no,menubar=no,scrollbars=no,resizable=no,location=no,status=no');
                if(wroxWin == null){
                    blocked = true;
                };
            }catch(e){
                blocked = true;
            };
            if(blocked){
                alert('验证弹窗已被拦截，请允许本页面弹出式窗口！');
            };
        };
    };

    function getRightUrl(url){
        var newUrl = url;
        if(/^thunder/i.test(url)){
            var key = url.replace(/thunder:\/\//i,'');
            var temp = decode64(key);
            newUrl = decodeURIComponent(temp.slice(2,-2));
        };
        if(/^magnet/i.test(newUrl)){
            var hash=newUrl.split('&')[0].substring(20) || newUrl.substring(20);
            if(hash.length==32){
                hash=base32To16(hash);
            };
            newUrl='magnet:?xt=urn:btih:' + hash;
        }else if(/^\/\//.test(url)){
            newUrl=location.protocol + url;
        }else if(/^\/(?!\/)/.test(url)){
            newUrl=location.protocol+'//'+location.host + url;
        };
        return newUrl;
    };

    function base32To16(str){
        if(str.length % 8 !== 0 || /[0189]/.test(str)){
            return str;
        };
        str = str.toUpperCase();
        var bin =  "", newStr = "", i;
        for(i = 0;i < str.length;i++){
            var charCode=str.charCodeAt(i);
            if(charCode<65)charCode-=24;
            else charCode-=65;
            charCode='0000'+charCode.toString(2);
            charCode=charCode.substr(charCode.length-5);
            bin+=charCode;
        };
        for(i = 0;i < bin.length;i+=4){
            newStr += parseInt(bin.substring(i,i+4),2).toString(16);
        };
        return newStr;
    };

    function getAttribute(e){
        var data = [] ;
        $.each(e.attributes, function() {
            if(this.specified && this.value.length>30) {
                data.push(this.value);
            };
        });
        if($(e).text().length>25) data.push($(e).text());
        return data;
    };

    function right_menu(){
        $('body').append(`
		<div class="115menu" style="width:97px;height:85px;z-index:9123456789;overflow:hidden;position:absolute;display:none;background-color:#D0D0D0">
			<ul style="padding:5px 7px;margin:0px;list-style:none;">
				<li><a href="javascript:;" class="right_menu00">全选</a></li>
				<li><a href="javascript:;" class="right_menu01">反选</a></li>
				<li><a href="javascript:;" class="right_menu02">复制所选</a></li>
				<li><a href="javascript:;" class="right_menu11">复制地址</a></li>
				<li><a href="javascript:;" class="right_menu12">种子下载1</a></li>
				<li><a href="javascript:;" class="right_menu13">种子下载2</a></li>
			</ul>
		</div>`);
        $('.115menu a').css({'line-height':'25px','text-decoration':'none','color':'#2C3E50','padding':'1px 5px','font-size':'16px','font-family':'arial'});//style="padding:0 64px 0 0
        $('.115menu a').hover(function(){
            $(this).css({'background-color':'#2777F8','color':'#FFF'});
        },function(){
            $(this).css({'background-color':'','color':'#2C3E50'});
        });
    };

    function list_menu(){
        setTimeout(function(){
            var $down=$('#js_float_content [val^="download"]',parent.document);
            $down.siblings('[class^="115"],[class="Dp"],[class="Local"]').remove();
            var $sed=$('li[file_type].selected');

            if($sed.length==1){
                var file = {};
                file['pid']=$sed.attr('pick_code');
                file['fid']=$sed.attr('file_id');
                file['sha']=$sed.attr('sha1') || '';
                file['size']=change($sed.attr('file_size'));
                file['cid']=$sed.attr('cate_id') || '';
                file['name']=name2($sed.attr('title'));
                var fileTxt = JSON.stringify(file);
                if($('#js_operate_box').is(':hidden')){
                    if(G.get('file_Down')){
                        $down.hide().eq('0').after(`<li class="115down" title="快捷下载文件" data=${fileTxt} style="display: list-item;"><a href="javascript:;"><i class="icon-operate"></i><span>快捷下载</span></a></li>`);
                    };
                    if($sed.is(':has(.duration):not([file_mode="4"])')){
                        var player2=player_api.match(/([a-z]{2,4})(p|\d|:)/i)[1].toUpperCase();
                        var cl = {'Dplayer':'Dp','本地播放':'Local'}[G.get('player')] || '115play';
                        var txt0 = ['Local','Dp'];
                        var txt1 = ['使用'+player2+'播放视频','使用Dplayer播放视频'];
                        var txt2 = [player2+'播放','Dp播放'];
                        for (var i=0; i<2; i++){
                            $down.eq('0').after(`<li class="${txt0[i]}" title=${txt1[i]} data=${fileTxt} style="display: list-item;"><a href="javascript:;"><span>${txt2[i]}</span></a></li>`);
                        };
                    };
                };
            };

            if($('#js_operate_box').is(':visible') &&G.get('file_Down') && $sed.length==1){
                $('#js_operate_box [menu="download"]').replaceWith(`<li class="115down" title="快捷下载文件" data=${fileTxt}><i class="icon-operate ifo-download"></i><span>快捷下载</span></li>`);
            };

            if($('li[file_type="0"].selected').length==0){
                if($sed.length>0){

                    if(G.get('M3U_list')){
                        if($('#js_operate_box').is(':hidden')){
                            $down.siblings('.115down').addBack().eq('-1').after('<li class="115M3Ulist" title="生成M3U播放列表" style="display:list-item;"><a href="javascript:;"><i class="icon-operate"></i><span>播放列表</span></a></li>');
                        }else if($('.115M3Ulist').length<1){
                            $('#js_operate_box li:eq(0)').after('<li class="115M3Ulist" title="生成M3U播放列表"><i class="icon-operate"></i><span>播放列表</span></li>');
                        };
                    };
                };
                if($sed.length>1){

                    if(G.get('down_batch') && navigator.userAgent.indexOf('115') == -1){
                        if($('#js_operate_box').is(':hidden')){
                            $down.hide().eq('0').after('<li class="115down_batch" title="批量下载文件" style="display:list-item;"><a href="javascript:;"><i class="icon-operate"></i><span>批量下载</span></a></li>');
                        }else if($('.115down_batch').length<1){
                            $('#js_operate_box [menu="download"]').replaceWith('<li class="115down_batch" title="批量下载文件"><i class="icon-operate ifo-download"></i><span>批量下载</span></li>');
                        };
                    };
                };
            };

            if(G.get('extract_file') && $sed.length>0 && $('li[file_type="1"].selected').length==0){
                var ifo = G.get('extract_save')=='复制'? 'ifo-copy':'ifo-move';
                if($('#js_operate_box').is(':hidden')){
                    $down.siblings('[class^="115down"]').addBack().eq('-1').after(`<li class="115extract" title="批量提取文件夹子文件" style="display:list-item;"><a href="javascript:;"><i class="icon-operate ${ifo}"></i><span>批量提取</span></a></li>`);
                }else if($('.115extract').length<1){
                    $('#js_operate_box [menu="download"],#js_operate_box [class^="115down"]').eq('-1').after(`<li class="115extract" title="批量提取文件夹子文件"><i class="icon-operate ${ifo}"></i><span>批量提取</span></li>`);
                };
            };
        }, 100);
    };

    function autobox(){
        if (document.compatMode == 'BackCompat') {
            var cW = document.body.clientWidth;
            var cH = document.body.clientHeight;
            var sW = document.body.scrollWidth;
            var sH = document.body.scrollHeight;
        }else{
            var cW = document.documentElement.clientWidth;
            var cH = document.documentElement.clientHeight;
            var sW = document.documentElement.scrollWidth;
            var sH = document.documentElement.scrollHeight;
        };
        var iW=window.innerWidth;
        var iH=window.innerHeight;
        var eW = $('#Dplayer')[0].offsetWidth;
        var eH = $('#Dplayer')[0].offsetHeight;


        if(sW > (iW || cW)){
            cW=iW || cW;
        };
        if(sH > (iH ||cH)){
            cH=iH || cH;
        };

        $('#Dplayer').css({'width':cW+'px','height':cH+'px'});
    };

    Date.prototype.Format = function (fmt) {
        var o = {
            "M+": this.getMonth() + 1,
            "d+": this.getDate(),
            "H+": this.getHours(),
            "m+": this.getMinutes(),
            "s+": this.getSeconds(),
            "q+": Math.floor((this.getMonth() + 3) / 3),
            "S": this.getMilliseconds()
        };
        if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
        for (var k in o)
            if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
        return fmt;
    };

    $(document).ready(function(){
        if(localHref.indexOf('https://115.com/') != -1) {
            if (typeof (unsafeWindow.USER_ID) != 'undefined') {
                GM_setValue('115ID', unsafeWindow.USER_ID);
                console.log('115账号已登录，账号ID获取成功！');
            } else {
                if (G.get('hide_officeLogin')){
                    $('.ltab-office').hide();
                };

                if (G.get('hide_qrcodeLogin')){
                    $('.login-scene,.login-footer span:eq(0),.login-footer i:eq(0)').hide();
                    $('[lg_rel="login"]').show();
                } else if ($('[lgb-nav="download"]').length > 0) {
                    $('[lgb-nav="download"]').attr('lgb-nav','login');
                };

                console.log('115账号未登录，账号ID获取失败！');
            };


            var $topEl = $('#js_top_panel_box [id="js_filter_btn"]').addClass('btn-line');
            if (G.get('show_Star')){
                $topEl.after('<a href="javascript:;" file_dialog_menu="star" class="button btn-line" id="js_star_list_btn"><i class="icon-operate ifo-fav"></i><span>星标</span></a>');
            };


            if (G.get('show_Task')){
                $topEl.after('<a href="javascript:;" class="button btn-line btn-upload" menu="offline_task"><i class="icon-operate ifo-linktask"></i><span>链接任务</span></a>');
            };


            if (G.get('show_Offline') && localHref.indexOf('https://115.com/?ct=file') != -1) {
                $topEl.after('<a href="javascript:;" class="button btn-line" tab_btn="wangpan" mode-tab="offline"><i class="icon-operate ifo-linktask"></i><span>云下载</span></a>');
                $('body').append(`
			<script>
					$('body').on('click','#js_top_panel_box [mode-tab="offline"]',function(e){
						window.open('https://115.com/?tab=offline&mode=wangpan', '_blank');
						return false;
			});
			</script>`);
            };

            if (G.get('hide_sidebar')){

                $('#site_left_bar').hide();
                $('.left-tvf [rel="page_top_btn"]').show();
            };

            $('.promptbar-caution').remove();

            if (G.get('file_Down')){
                var herfd = 'li[file_type]:not([down_button="1"])';
                $('body').on('mouseenter',herfd,function(){
                    var $El = $(this).attr('down_button',1);
                    $El.find('.file-opr a[menu^="download"]').hide();
                    $El.find('.file-opr').prepend('<a class="115down" href="javascript:;"title="快捷下载文件"><i class="icon-operate ifo-download"></i><span>快捷下载</span></a>');



                });
            };


            var herfv = 'li[file_type="1"]:has(.duration):not([file_mode="4"],[paly_button="1"])';
            var player2=player_api.match(/([a-z]{2,4})(p|\d|:)/i)[1].toUpperCase();
            $('body').on('mouseenter',herfv,function(){
                var $El = $(this).attr('paly_button',1);

                var cl = {'Dplayer':'Dp','本地播放':'Local'}[G.get('player')] || '115play';
                $El.find('.name').addClass(cl).removeAttr('menu');

                var txt0 = ['Local','Dp'];
                var txt1 = ['使用'+player2+'播放视频','使用Dplayer播放视频'];
                var txt2 = [player2+'播放','Dp播放'];
                if (!G.get('hide_play')){
                    for (var i=0; i<2; i++){
                        $El.find('.file-opr').prepend('<a href="javascript:;" class='+txt0[i]+' title='+txt1[i]+'><span>'+txt2[i]+'</span></a>');
                    };
                };
                $El.not('.name').dblclick(function(){
                    var type = 'dblclick';
                    var pid1 = $El.attr('pick_code');
                    var video = {'pid':pid1};
                    palyData(video,type);
                    return false;
                });
            });
            $('body').on('mouseenter','li[rel="item"]:not([batch_button="1"])',function(e){
                var $El=$(this).attr('batch_button',1);
                $El.find('.checkbox').addBack().click(function(){
                    list_menu();
                });
                $El.contextmenu(function(){
                    list_menu();
                });
            });
            $('body').on('mouseenter','.list-header:not([batch_button="1"])',function(){
                var $El=$(this).attr('batch_button',1);
                $El.find('[menu="file_check_all"]').click(function(){
                    list_menu();
                });
            });

            // 搜索显示面板加宽
            add_TopButton();
        };

        if(localHref.indexOf('https://captchaapi.115.com') != -1 && window.top==window.self) {
            window.focus();
            toastr.info('验证成功后本页面将自动关闭.');
            var t_close;
            $('#js_ver_code_box [rel="verify"]').click(function (){
                t_close=setTimeout(function(){
                    console.log('验证正确');

                    window.open('','_self');
                    window.close();
                }, 200);
                return false;
            });
            $('.vcode-hint').on('DOMNodeInserted',function(e){
                console.log('验证错误！');
                clearTimeout(t_close);
            });
        };

        if(localHref.match(/115\.com\/\?ct=play|v\.anxia\.com|115vod\.com/) != null) {
            $('.bar-side ul').prepend(`<li><a href="javascript:;" class="openPiP"
			style="float:left;width:40px;height:20px;margin:10px 5px;border-radius:3px;font-size:12px;text-align:center;background:#666;color:#fff;opacity:0.7;">
			<s>画中画</s><div class="tooltip" >开启画中画</div></a></li>`);
            if (G.get('web_fullscreen')){
                $('body').append(`<script>$('.bar-side [rel="web_fullscreen"]').click();</script>`);
            };
        };
		
        // if(localHref.indexOf('https://v.anxia.com/') != -1) {
		if (/v\.anxia\.com|115vod\.com/.test(localHref)){	

            function invalMouseRight() {
                // 屏蔽鼠标右键
                // if ((/(anxia)/g).test(document.domain)) {
                    document.body.setAttribute("oncontextmenu", "return false;");
                // }

                document.addEventListener('keydown', function (event){
                    if (event.key === 'Alt') {
                        KeyTools.flagKeyStat("altdown", true);

                    }else if (event.altKey && event.key.toLowerCase() === 'x'){
                        // 组合键
                        KeyTools.flagKeyStat("altdown", false);
                    }

                });

                // 屏蔽按键响应
                document.addEventListener('keyup', function(event) {
                    // #fff-ael 检查是否按下了特定的键或键组合
                    // 比如阻止F5刷新页面
					
					function setOffVal(offLenX, offLenY, xValue, yValue){
						let offTransform = ``;
						let offVal = 0;
						if(xValue != 0 || offLenX != 0) {
								
							offVal = xValue + offLenX;
							offTransform += ` translateX(${offVal}px)`;
						}
						
						if(yValue != 0 || offLenY != 0) {
							
							offVal = yValue + offLenY;
							offTransform += ` translateY(${offVal}px)`;
						}
						
						return offTransform;
					}
					
					function resetVerticalParamZoom(videoElement){
						let currentTransform = videoElement.style.transform || '';
						if( currentTransform.includes('rotate(90deg)') || currentTransform.includes('rotate(270deg)') )
						{
							let lastZoom = GM_getValue('lastZoomH') || 1.0;
							videoElement.style.zoom = lastZoom;
							
						}else{
							videoElement.style.zoom = '1.0';
							
						}
					}
					
					function resetVerticalParamOff(videoElement){
						let currentTransform = videoElement.style.transform || '';
						if( currentTransform.includes('rotate(90deg)') || currentTransform.includes('rotate(270deg)') )
						{
							let lastOffVal = GM_getValue('lastOffTrans') || 0;
							if(lastOffVal !== 0){
								currentTransform = currentTransform.replace(/translateX\([^)]+\)/g, '').trim();
								currentTransform = currentTransform.replace(/translateY\([^)]+\)/g, '').trim();
								let offIncX = 1;
								if( currentTransform.includes('rotate(270deg)')) {
									offIncX = -offIncX;
								}
								if(currentTransform.includes('rotateY(180deg)')) {
									offIncX = -offIncX;
								}
								let offTransform = setOffVal(lastOffVal*offIncX, 0, 0, 0);
								currentTransform += offTransform;
								videoElement.style.transform = currentTransform;
							}
							
						}
					}

                    if (event.key === ' ') {
                        console.log(event.key + '键弹起');
					
					}else if (event.shiftKey && (event.key === 'ArrowLeft'
							|| event.key === 'ArrowRight'
							|| event.key === 'ArrowUp'
							|| event.key === 'ArrowDown')) {

                            const videoElement = document.getElementById('js-video');
							if (videoElement) {
								
								// 设置偏移
								let currentTransform = videoElement.style.transform || '';
								const matchX = currentTransform.match(/translateX\((-?\d+)px\)/);
								const matchY = currentTransform.match(/translateY\((-?\d+)px\)/);
								let xValue = 0;
								let yValue = 0;
								if (matchX) {
									xValue = parseInt(matchX[1]); // 提取匹配的数字部分
								}
								if (matchY) {
									yValue = parseInt(matchY[1]); // 提取匹配的数字部分
								}

							  currentTransform = currentTransform.replace(/translateX\([^)]+\)/g, '').trim();
							  currentTransform = currentTransform.replace(/translateY\([^)]+\)/g, '').trim();
							  let offIncX = 1;
							  let offIncY = 1;
							  let offLen = 0;
							  let offvh = 'Horizontal';
							  if( currentTransform.includes('rotate(90deg)')  || currentTransform.includes('rotate(70deg)') 
							|| currentTransform.includes('rotate(270deg)')  || currentTransform.includes('rotate(250deg)') ){
								  offvh = 'vertical';	//  竖屏
								  offLen = 75;
							  }else{
								  offvh = 'Horizontal';	// 横屏
								  offLen = 100;
							  }
							  
							   if( currentTransform.includes('rotate(180deg)') || currentTransform.includes('rotate(200deg)')
							|| currentTransform.includes('rotate(270deg)') || currentTransform.includes('rotate(250deg)') ){
								  offIncX = -offIncX;
								  offIncY = -offIncY
							  }
							  
							  if(currentTransform.includes('rotateY(180deg)')) {
								  offIncX = -offIncX;
							  }
							  
							  if(currentTransform.includes('rotateX(180deg)')) {
								  offIncY = -offIncY;
							  }
							  
							  let offTransform = ``;
							  let lastOffVal = 0;
							  if(event.key === 'ArrowLeft'){
								  if(offvh == 'Horizontal'){
									  offTransform = setOffVal(offLen*offIncX, 0, xValue, yValue);
								  }else if(offvh == 'vertical'){
									  offTransform = setOffVal(0, -offLen*offIncY, xValue, yValue);
								  }
								  
							  }else if(event.key === 'ArrowRight'){
								  if(offvh == 'Horizontal'){
									  offTransform = setOffVal(-offLen*offIncX, 0, xValue, yValue);
								  }else if(offvh == 'vertical'){
									  offTransform = setOffVal(0, offLen*offIncY, xValue, yValue);
								  }
							  }
							  
							  if(event.key === 'ArrowUp'){
								  if(offvh == 'Horizontal'){
									  offTransform = setOffVal(0, offLen*offIncY, xValue, yValue);
								  }else if(offvh == 'vertical'){
									  offTransform = setOffVal(offLen*offIncX, 0, xValue, yValue);
									  lastOffVal = Math.abs(offLen*offIncX + xValue);
								  }
								  
							  }else if(event.key === 'ArrowDown'){
								   if(offvh == 'Horizontal'){
									  offTransform = setOffVal(0, -offLen*offIncY, xValue, yValue);
								  }else if(offvh == 'vertical'){
									  offTransform = setOffVal(-offLen*offIncX, 0, xValue, yValue);
									  lastOffVal = -Math.abs(-offLen*offIncX + xValue);
								  }
							  }
							  
							  currentTransform += offTransform;
							  videoElement.style.transform = currentTransform;
							  if(offvh == 'vertical') {
									  //  竖屏
									  GM_setValue('lastOffTrans', lastOffVal);
								  }
							  Common.showMessage("移动。。。" ,  2000);
							}

						event.stopImmediatePropagation();	// 屏蔽按键响应
					
					}else if (event.key === 'ArrowLeft') {
							console.log(event.key + '键弹起');
							Common.showMessage("方向键。。。", 1000);
					
					}else if (event.key === 'ArrowRight'){
                        var video = $('#js-video')[0];
						if (!video) return;
						
						video.currentTime += 5;
						Common.showMessage("快进。。。", 1000);

                    }else if (event.key === 'F2'){
                        // Screenshot.takeScreenshot();
						const videoElement = document.getElementById('js-video');

						let currentTransform = videoElement.style.transform || '';
						var button = null;
						if( currentTransform.includes('rotate(90deg)')  || currentTransform.includes('rotate(70deg)') 
							|| currentTransform.includes('rotate(270deg)')  || currentTransform.includes('rotate(250deg)') )
						{
							button = document.querySelector('[btn="rotate"][rotate="left"]');
							
						}else{
							button = document.querySelector('[btn="rotate"][rotate="right"]');
						}
						
                        if (button) {
                            Common.sendClickEvent(button);
							
							resetVerticalParamZoom(videoElement);
							resetVerticalParamOff(videoElement);
                        }

                    }else if (event.key === 'F3'){
                        const button = document.querySelector('[btn="rotate"][rotate="horizontal"]');
                        if (button) {
                            Common.sendClickEvent(button);
							
							const videoElement = document.getElementById('js-video');
							resetVerticalParamOff(videoElement);
                        }

                    }else if (event.key === 'F4'){
                        const button = document.querySelector('[btn="rotate"][rotate="vertical"]');
                        if (button) {
                            Common.sendClickEvent(button);
							
							const videoElement = document.getElementById('js-video');
							resetVerticalParamOff(videoElement);
                        }

                    }else if (event.key === 'F5'){
						const m3u8Error = document.getElementById("js-m3u8_error");
						if(m3u8Error.style.display !== "none"){
							// 模拟点击重新播放按钮
							const button = document.querySelector('[btn="reload"]');
							if (button) {
								Common.sendClickEvent(button);
							}
							
                        }else{
							// 刷新缓存
							// __HLS.setConfig("maxBufferLength", 60*5);
							__HLS.setConfig("maxBufferLength",  60 * 15);
							var video = $('#js-video')[0];
							if(video.currentTime > 0) {
								__HLS.setConfig('startPosition',  video.currentTime);
							}
							__HLS.reload();
							
						}

                    }else if (event.key === 'F6'){
                        if (window.__SETTING) {
                            var video = $('#js-video')[0];
                            const filterStr = video.style.filter;
                            if (Common.isEmptyString(filterStr)){
                                __SETTING.setFilter("brightness", 100);
                                __SETTING.setFilter("contrast", 100);
                                __SETTING.setFilter("saturate", 83);
                                Common.showMessage("调低-饱和度。。。", 3000, "#346e34");

                            }else if (filterStr.includes("saturate(83%)")){
                                MyFilter.applayFilter("saturate(82%) url(#myGammaLow)");
                                Common.showMessage("低伽玛。。。", 3000, "#6d6dda");

                            }else if (filterStr.includes(`url("#myGammaLow")`)){
                                MyFilter.applayFilter("url(#myGammaHigh)");
                                Common.showMessage("高伽玛。。。", 3000, "#95bdf5");

                            }else if (filterStr.includes(`url("#myGammaHigh")`)){
                                __SETTING.setFilter("brightness", 38);
                                __SETTING.setFilter("contrast", 110);
                                __SETTING.setFilter("saturate", 100);
                                Common.showMessage("调低-亮度。。。", 3000, "#100f0f");
								
							 }else if (filterStr.includes("brightness(38%)")){
                                __SETTING.setFilter("brightness", 100);
                                __SETTING.setFilter("contrast", 120);
                                __SETTING.setFilter("saturate", 90);
                                Common.showMessage("调高-对比度。。。", 3000, "#100f0f");

                            }else if (filterStr.includes("contrast(120%)")){
                                MyFilter.applayFilter(null);
                                Common.showMessage("原色。。。", 3000, "#e6efe6");

                            }else {
                                MyFilter.applayFilter(null);
                                Common.showMessage("原色。。。", 3000, "#e6efe6");
                            }

                            // let ret = Common.checkPassTime("filter", 2000)
                            // if (ret == 0) {
                            //     __SETTING.setFilter("brightness", 100);
                            //     __SETTING.setFilter("contrast", 100);
                            //     __SETTING.setFilter("saturate", 82);
                            // }else if (ret == 1){
                            //     __SETTING.setFilter("brightness", 38);
                            //     __SETTING.setFilter("contrast", 110);
                            //     __SETTING.setFilter("saturate", 100);
                            // }else if (ret == 2){
                            //     MyFilter.applayFilter("saturate(82%) url(#myGammaLow)");
                            // }else if (ret == 3){
                            //     MyFilter.applayFilter("url(#myGammaHigh)");
                            // }
                        }

					}else if (event.key === 'F11'){
                        Screenshot.takeScreenshot();
						
                    }else if (event.key === 'Alt') {
                        if (!KeyTools.isKeyDown("altdown")) return;
						if (event.location === 2){
							// 右边alt
							KeyTools.checkAndExcPassTime("right_altdown", 2000)
							
							return;
						}

                        KeyTools.flagKeyStat("altdown", false);

                        if (KeyTools.checkAndExcPassTime("altdown", 2000) == 0) {
                            const sss = document.querySelectorAll('.btn-cle s')[0];
                            if (!sss) return;

                            if (sss.textContent !== "1.0倍") {
                                KeyTools.clearPassTime("altdown");

                                const aaa = document.querySelector('.popup-menu .cell a[reat="1"]');
                                if (aaa) {
                                    Common.sendClickEvent(aaa);
                                    Common.showMessage("原速度。。。", 2000);
                                }
                            }
                        }

                    }else if (event.key.toLowerCase() === 'z'){
                        if (KeyTools.checkPassTime("altdown", 2000) > 0){
                            const aaa = document.querySelector('.popup-menu .cell a[reat="0.5"]');
                            if (aaa) {
                                Common.sendClickEvent(aaa);
                                Common.showMessage("0.5倍速。。。", 2000);
                            }
                        }


                    }else if (event.key.toLowerCase() === 'x'){
                        if (KeyTools.checkPassTime("altdown", 2000) > 0) {
                            const aaa = document.querySelector('.popup-menu .cell a[reat="1.5"]');
                            if (aaa) {
                                Common.sendClickEvent(aaa);
                                Common.showMessage("1.5倍速。。。", 2000);
                            }
                        }

                    }else if (event.key.toLowerCase() === 'c') {
                        if (KeyTools.checkPassTime("altdown", 2000) > 0) {
                            const aaa = document.querySelector('.popup-menu .cell a[reat="2"]');
                            if (aaa) {
                                Common.sendClickEvent(aaa);
                                Common.showMessage("2.0倍速。。。", 2000);
                            }
                        }
                        event.stopImmediatePropagation();	// 屏蔽按键响应

					}else if (event.altKey && event.key.toLowerCase() === 'm') {
                        //if (KeyTools.checkPassTime("right_altdown", 2000) > 0) {
                            const videoElement = document.getElementById('js-video');
							if (videoElement) {  
								let currentTransform = videoElement.style.transform || '';
							  // 重新设置zoom值
							  videoElement.style.zoom = '1.0';
							  
							  // 设置偏移
							  currentTransform = currentTransform.replace(/translateX\([^)]+\)/g, '').trim();
							  currentTransform = currentTransform.replace(/translateY\([^)]+\)/g, '').trim();
							  videoElement.style.transform = currentTransform;
							  
							  if( currentTransform.includes('rotate(90deg)') || currentTransform.includes('rotate(270deg)')) {
								  //  竖屏
								  GM_setValue('lastZoomH', '1.0');
								  GM_setValue('lastOffTrans', 0) ;
							  }
							  Common.showMessage("缩放还原。。。",  2000);
							}
                        //}
						event.stopImmediatePropagation();	// 屏蔽按键响应
						
					}else if (event.altKey && event.key.toLowerCase() === ',') {
                        //if (KeyTools.checkPassTime("right_altdown", 2000) > 0) {
                            const videoElement = document.getElementById('js-video');
							if (videoElement) {
								  let currentTransform = videoElement.style.transform || '';
								  let currentZoom = parseFloat(videoElement.style.zoom) || 1.0; // 默认值为1
								  currentZoom -= 0.15;
								  currentZoom = currentZoom.toFixed(2);
								  
								  // 重新设置zoom值
								  videoElement.style.zoom = currentZoom.toString();
								   if( currentTransform.includes('rotate(90deg)') || currentTransform.includes('rotate(270deg)')) {
									  //  竖屏
									  GM_setValue('lastZoomH', currentZoom);
								  }
								  
								  Common.showMessage("缩小。。。" + currentZoom,  2000);
							}
                        //}
						event.stopImmediatePropagation();	// 屏蔽按键响应
						
					}else if (event.altKey && event.key.toLowerCase() === '.') {
                        //if (KeyTools.checkPassTime("right_altdown", 2000) > 0) {
                            const videoElement = document.getElementById('js-video');
							if (videoElement) {
								  let currentTransform = videoElement.style.transform || '';
								  let currentZoom = parseFloat(videoElement.style.zoom) || 1.0; // 默认值为1
								  currentZoom += 0.15;
								  currentZoom = currentZoom.toFixed(2);
								  
								  // 重新设置zoom值
								  videoElement.style.zoom = currentZoom.toString();
								   if( currentTransform.includes('rotate(90deg)') || currentTransform.includes('rotate(270deg)')) {
									  //  竖屏
									  GM_setValue('lastZoomH', currentZoom);
								  }
								  
								  Common.showMessage("放大。。。" + currentZoom,  2000);
							}
                        //}
						event.stopImmediatePropagation();	// 屏蔽按键响应
					
					}else if (event.altKey && event.key.toLowerCase() === '/') {
                        // Screenshot.takeScreenshot();
						const videoElement = document.getElementById('js-video');
						
						let currentTransform = videoElement.style.transform || '';
						const matchRotateValStr = currentTransform.match(/rotate\((-?\d+)deg\)/);
						let rotateVal = 0;
						if (matchRotateValStr && matchRotateValStr[1]) {
							rotateVal = parseInt(matchRotateValStr[1]); // 提取匹配的数字部分
						}else{
							currentTransform += ' rotate(0deg)';
						}
						
						let newRotateVal = 0;
						if(rotateVal == 90 || rotateVal == 270){
							newRotateVal = rotateVal - 20;
						}else if((rotateVal > 45 && rotateVal < 90) || (rotateVal  > 225 && rotateVal < 270)){
							newRotateVal = rotateVal + 20;
						}
						
						if(rotateVal == 0 && (currentTransform.includes('rotateY(180deg)') || currentTransform.includes('rotateX(180deg)'))){
							newRotateVal = rotateVal - 20;
						}else if(rotateVal < 0 && rotateVal > -45){
							newRotateVal = 0;
							
						}else if(rotateVal == 0 || rotateVal == 180){
							newRotateVal = rotateVal + 20;
						}else if((rotateVal > 0 && rotateVal < 45) || (rotateVal  > 180 && rotateVal < 225)){
							newRotateVal = rotateVal - 20;
						}

						currentTransform = currentTransform.replace(/rotate\(-?\d+deg\)/,  `rotate(${newRotateVal}deg)`);
						videoElement.style.transform = currentTransform;
						Common.showMessage("便宜。。。"+ newRotateVal,  2000);
						
						event.stopImmediatePropagation();	// 屏蔽按键响应

                    }else if (event.altKey && event.key.toLowerCase() === 'w') {
                        if (FloatWindow.isShow()){
                            FloatWindow.hideWindow();

                            // Common.simulateKey('shift');
                            // Common.sleep(500);
                            // Common.simulateKey('q');
                        }else {
                            FloatWindow.showWindow();

                            // Common.simulateKey('shift');
                            // Common.sleep(500);
                            // Common.simulateKey('w');
                        }


                        event.stopImmediatePropagation();	// 屏蔽按键响应
					
					}else if (event.altKey && event.key.toLowerCase() === 'a') {
                        if (FloatWindow.isShow()){
                            FloatWindow.autoCloseCount = 30;
                        }else {
							FloatWindow.showWindow(60);
                        }


                        event.stopImmediatePropagation();	// 屏蔽按键响应
						
					}else if (event.altKey && event.key.toLowerCase() === 's') {
                        if(FloatWindow.pause){
							FloatWindow.pause = false;
							Common.showMessage("恢复。。。", 3000, "#116dda");
							
						}else{
							FloatWindow.pause = true;
							Common.showMessage("暂停。。。", 3000, "#6d6d11");
							let imgLoadingEle = document.querySelector('.img-loading');
							imgLoadingEle.style.display = 'flex';
							imgLoadingEle.innerText = '暂停！！！';
						}

                        event.stopImmediatePropagation();	// 屏蔽按键响应
						
					}else if (event.altKey && event.key.toLowerCase() === 'e') {
                        FloatWindow.setTimeOff();

                        event.stopImmediatePropagation();	// 屏蔽按键响应
                    
					}else if (event.altKey && event.key.toLowerCase() === 'd') {
                        FloatWindow.setTimeOff_02();
						
						if(FloatWindow.pause){
							FloatWindow.pause = false;
							Common.showMessage("恢复。。。", 3000, "#116dda");
							
						}

                        event.stopImmediatePropagation();	// 屏蔽按键响应
						
                    }else if (event.altKey && event.key.toLowerCase() === '1') {
                        FloatWindow.setTimeOff(FloatWindow.offTimeSS  + 1);

                        event.stopImmediatePropagation();	// 屏蔽按键响应
						
					}else if (event.altKey && event.key.toLowerCase() === '2') {
                        FloatWindow.setTimeOff(FloatWindow.offTimeSS  + 2);

                        event.stopImmediatePropagation();	// 屏蔽按键响应
						
					}else if (event.altKey && event.key.toLowerCase() === '3') {
                        FloatWindow.setTimeOff(FloatWindow.offTimeSS  + 3);

                        event.stopImmediatePropagation();	// 屏蔽按键响应
						
					}else if (event.altKey && event.key.toLowerCase() === '4') {
                        FloatWindow.setTimeOff(0);

                        event.stopImmediatePropagation();	// 屏蔽按键响应
					
					}else{
                        // event.preventDefault();
                        event.stopImmediatePropagation();
                        console.log(event.key + '键已被屏蔽');
                    }
                });

                // 显示最近缓存开始位置
                Common.updatePressbar();
            }
            invalMouseRight();

            function initVideoSetting(){
                if (window.__SETTING == undefined) {
                    var video = $('#js-video')[0];
                    var $video_box = $('#js-video_box');

                    var videoSetting = new VideoSetting(video, $video_box);
                    window.__SETTING = videoSetting;
                }

                console.log(__SETTING.getVideoBoxWH());
            }
            initVideoSetting();
            MyFilter.initSVGFilters();


            setTimeout(function (){
                // 去除标题中的115尾巴
                Common.rename115Title();
                // 删除右下角的广告
                Common.delGuanGao();
                // 去除标题中的115尾巴
                add_playInfoPanel();
                // 移除正在加载图标
                Common.delLoadingIcon();
				// 移除从开头播放
				Common.delRestartTools();
				// 修正进度条长度
				// Common.resetProgressWidth();
                // 增加预览窗口
                FloatWindow.addFloatWindow();
            }, 3000);

        };

        if (/javbus|busjav|busfan|fanbus|buscdn|cdnbus|dmmsee|seedmm|busdmm|dmmbus|javsee|seejav/.test(localHref)){
            // javbus的处理
            function removeLinkClick(){
                // 移除磁力链接点击会打开下载软件
                const elements = document.querySelectorAll('#magnet-table td[onclick]');
                for (let i = 0; i < elements.length; i++) {
                    elements[i].removeAttribute('onclick');
                }
            }

            setTimeout(function (){
                removeLinkClick();
            }, 3000);


            function addKeyListener(){
                // 按键响应
                document.addEventListener('keyup', function(event) {
                    if (event.key === ' ') {
                        console.log(event.key + '键弹起');

                    }else if (event.altKey && event.key.toLowerCase() === 'w') {
                        // 重新发现磁力链接
                        offline.addButton();
                        offline.addSelect();

                        event.stopImmediatePropagation();	// 屏蔽按键响应
                    }

                });
            }
            addKeyListener();
        }

            var oldVer = GM_getValue('version') || '';
        if (G.get('show_Update') && oldVer != newVersion){
            var txt=`115优化大师 ${newVersion} 更新日志：\n更新日期：2023年8月21日 \n1、修复页面升级导致隐藏侧边栏等功能异常问题；\n2、升级部分依赖库版本。`
            setTimeout(function(){
                alert(txt);
            },2000);
            GM_setValue('version',newVersion);
        };

    });

    if(localHref.indexOf('https://115.com/?cid=0&offset=0&mode=wangpan') != -1){
        window.onload=function(){
            if (G.get('show_Alidity') && typeof unsafeWindow.USER_ID != 'undefined'){
                var login_info = 'http://passportapi.115.com/app/1.0/web/9.2/login_log/login_devices';
                AjaxCall(login_info,function(error,htmlTxt) {
                    var json = JSON.parse(htmlTxt);


                    if(json.state==1) {
                        var time = json.data.last.utime;
                        var date = new Date(time * 1000);
                        var loginTime = date.Format("yyyy年MM月dd日 HH:mm");
                        toastr.success('上次登录时间：'+loginTime,{timeOut:5000});

                        console.log('登录时间:\n'+loginTime);
                    } else {
                        var txt=json.error || '网络错误，未知时间！';
                        toastr.warning('上次登录时间：'+txt,{timeOut:5000});
                    };
                });
            };

        };
    };

    if (localHref.match(/^http:\/\/(115\.com\/web\/lixian)|(videotsgo\.115\.com)\/$/) != null) {
        var m3u8 = GM_getValue('m3u8List');
        var video = GM_getValue('videoInfo');
        var titleTxt = video.name;
        var pickID = video.pid;
        var folderID = video.cid;
        var videoID = video.fid;
        var size = video.size;
        var sha = video.sha;
        var z = video.quality;
        var skipTime = G.get('skip_titles');
        var skipTime2 = G.get('skip_credits');
        GM_setValue('stop',true);

        $('pre').remove();
        $('body').html('');
        $('head').html(`<meta http-equiv="Content-Type" content="text/html; charset=GBK"><title>${titleTxt} ${size}</title>`);
        GM_addStyle(`html,body,div{margin:0;padding:0;border:0;outline:0;background:transparent}`);
        GM_addStyle(GM_getResourceText('dplayerCss'));
        $('body').append('<div id="Dplayer"></div>');
        function playVideo(m3u8){
            var dp = new DPlayer({
                container: $('#Dplayer')[0],
                screenshot: true,
                volume: 1,
                video:
                    {
                        quality: m3u8,
                        defaultQuality: z,
                    },
                contextmenu:
                    [
                        {
                            text: '下载视频',
                            click: function(t) {
                                var key={pc:pickID,fid:videoID};
                                download(key).then(function(data){
                                    if(data[0]){
                                        GM_openInTab(data[0]);
                                        if(G.get('show_sha')){
                                            setTimeout(function(){
                                                prompt('文件下载中，校验码(SHA1)为：',sha);
                                            }, 1000);
                                        };
                                    }else{
                                        alert('下载失败！'+data[1]);
                                    };
                                });
                            }
                        },
                        {
                            text: '删除视频',
                            click: function(t) {
                                dp.pause();
                                var a = confirm('确认删除 '+titleTxt+' 视频文件？');
                                if (a){
                                    offline.del(videoID)
                                };
                            }
                        },
                        {
                            text: '查看文件夹',
                            click: function(t) {
                                GM_openInTab(`https://115.com/?cid=${folderID}&offset=0&mode=wangpan`,false);
                            }
                        },
                        {
                            text: '删除文件夹',
                            click: function(t) {
                                var a = confirm('确认删除 '+titleTxt+' 视频所属文件夹？');
                                if (a){
                                    offline.del(folderID);
                                };
                            }
                        },
                        {
                            text: '设置星标',
                            click: function(t) {
                                var n=1;
                                offline.setStar(videoID,n);
                            }
                        },
                        {
                            text: '取消星标',
                            click: function(t) {
                                var n=0;
                                offline.setStar(videoID,n);
                            }
                        },
                        {
                            text: '重命名',
                            click: function(t) {
                                offline.newName(videoID,titleTxt);
                            }
                        },
                    ],
            });

            unsafeWindow.dp = dp;
            unsafeWindow.$ = $;

            $('#Dplayer').click();
            $('.dplayer-menu').css('width','98px');
            $('.dplayer-setting-loop,.dplayer-mobile-play,.dplayer-menu-item:gt(-3)').hide();
            if(m3u8.length >1){
                $('.dplayer-quality button').css('color','Lime');
            };

            $('.dplayer-quality').after(`
			<div class="dplayer-icon openPiP" data-balloon="画中画" data-balloon-pos="up">
				<span class="dplayer-icon-content"><svg width="22" height="22" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"><g fill="#E6E6E6" fill-rule="evenodd"><path d="M17 4a2 2 0 012 2v6h-2V6.8a.8.8 0 00-.8-.8H4.8a.8.8 0 00-.794.7L4 6.8v8.4a.8.8 0 00.7.794l.1.006H11v2H4a2 2 0 01-2-2V6a2 2 0 012-2h13z"></path><rect x="13" y="14" width="8" height="6" rx="1"></rect></g></svg></span>
			</div>`);

            dp.on('loadstart', function (){
                dp.notice('视频加载中,请稍侯。', 1000);
            });

            var a = 0;
            dp.on('loadeddata', function () {
                dp.notice('视频加载完成。', 1000);
                a++;
                if(a!=1) return;

                setTimeout(function(){
                    getHistory(pickID).then(function(onTime){
                        if(G.get('online_List') && onTime > skipTime){
                            dp.seek(onTime);
                            dp.notice('已跳转到上次观看进度'+tranTime(onTime), 2500);
                        }else if(skipTime>0){
                            dp.seek(skipTime);
                            dp.notice('已跳过片头'+skipTime+'秒', 2500);
                        };

                        if(document.hidden && G.get('Tab_ing')){
                            return;
                        };
                        dp.play();
                    });

                }, 1000);

            });

            var b=0;
            dp.on('timeupdate', function(){
                if((dp.video.duration - dp.video.currentTime) <= (skipTime2 >0? skipTime2:30)){
                    var ed=1;
                    b++
                    if(skipTime2>0){
                        dp.notice('已跳过片尾'+skipTime2+'秒', 2500);
                        dp.pause();
                        if(b%2==0){
                            setTimeout(function(){
                                alert('视频已播放结束！');
                            }, 1000);
                        };
                    };
                }else{
                    var ed=0;
                };
                GM_setValue('end',ed);
            });

            var c=0;
            var up;
            function upTime(out){
                up = setInterval(function (){
                    var end=GM_getValue('end') || 0;
                    var newTime=dp.video.currentTime.toFixed(0);
                    var t =parseInt(dp.video.currentTime-c);
                    c=dp.video.currentTime;

                    var key = {
                        'op': 'update',
                        'pick_code': pickID,
                        'time': end? 0:newTime,
                        'definition': end,
                        'category': 1
                    };
                    var history_url='https://webapi.115.com/files/history';
                    if(end || (c >= 30 && Math.abs(t) > 1)){
                        offline.getData(history_url,$.param(key)).then(function(json){
                            json.state? console.log('上传播放记录成功！'):console.log('上传播放记录失败，'+json.error);
                        });

                    };

                    if(dp.video.paused || dp.video.error || end){
                        GM_setValue('stop',true);
                        clearInterval(up);
                    };

                }, out);
            };

            if (G.get('online_List')){
                dp.on('play', function(){
                    var stop=GM_getValue('stop');
                    if(stop){
                        GM_setValue('stop',false);
                        upTime(3000);
                    };
                });

                dp.on('seeked', function(){
                    if(dp.video.paused){
                        upTime(50);
                    };
                });
            };


            dp.on('error', function(){
                alert('视频加载失败！');
            });

            dp.on('ended', function(){
                alert('视频播放结束！');
            });
        };
        playVideo(m3u8);
        autobox();
    };

    var offline = function(){
        return {
            getSign:function(key,save_name){
                return new Promise(function(resolve, reject){
                    if (/^\w+=/.test(key)){
                        resolve(key);
                        return;
                    };

                    var UserID = GM_getValue('115ID') || '';
                    var cid = G.get('diy_folder')? GM_getValue('offlineFolder'):'';
                    var title = save_name? save_name:'';
                    GM_xmlhttpRequest({
                        method: 'GET',
                        url: sign_url,
                        responseType: 'json',
                        headers: {
                            "User-Agent": UA,
                            Origin: "https://115.com",
                        },
                        onload: function(result){
                            if (result.responseText.indexOf('html')!= -1) {
                                toastr.error('请先登录115网盘账号！','离线任务添加失败。');
                                setTimeout(function(){
                                    var a = confirm('立即打开115网盘登录页面？');
                                    if (a){
                                        GM_openInTab('https://115.com/?mode=login',false);
                                    };
                                }, 3000);
                                return;
                            };
                            var data = {
                                uid: UserID,
                                sign: result.response.sign,
                                time: result.response.time,
                                wp_path_id: cid,
                                savepath: title
                            };

                            if($.isPlainObject(key)){
                                var value=$.param($.extend(data,key));

                            }else{
                                var value=$.param(data)+`&url=${key}`;
                            };
                            resolve(value);
                        },
                        onerror: function(error){
                            reject(error);
                        },
                    });
                });
            },

            getData:function(herf,key,save_name){
                return offline.getSign(key,save_name).then(function(value){
                    return new Promise(function(resolve, reject){
                        GM_xmlhttpRequest({
                            method: 'POST',
                            data: value,
                            url: herf,
                            responseType: 'json',
                            headers: {

                                "User-Agent": UA,
                                "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
                                "Accept": "application/json, text/javascript; q=0.01",
                                Origin: "https://115.com",
                                "X-Requested-With": "XMLHttpRequest"
                            },
                            onload: function(result){
                                resolve(result.response);
                            },
                            onerror: function(error){
                                reject(error);
                            },
                        });
                    });
                });
            },

            del:function(id){
                if(id == 0){
                    alert('网盘根目录,不可删除！');
                    return ;
                };
                var Link = 'http://115.com/?ct=lixian&ac=get_id';
                AjaxCall(Link,function(error,htmlTxt){
                    var json = JSON.parse(htmlTxt);
                    if(json.cid == id){
                        alert('云下载（离线保存默认文件夹），不可删除！');
                        return ;
                    };

                    var del_url ='https://webapi.115.com/rb/delete';
                    var key = 'fid='+id;
                    offline.getData(del_url,key).then(function(json){

                        if(json.state){
                            var a = confirm('删除成功，可从回收站还原。是否立即关闭本页面？');
                            if (a){

                                window.open('','_self');
                                window.close();
                            };
                        } else {
                            alert('删除失败:'+json.error);
                        };
                    });
                });
            },

            setStar:function (fid,n){
                var txt = {'1':'设置','0':'取消'}[n];
                var star_url ='https://webapi.115.com/files/star';
                var key = `file_id=${fid}&star=${n}`;
                offline.getData(star_url,key).then(function(json){

                    json.state ? alert(txt+'星标成功！') : alert(txt+'星标失败:'+json.error);
                });
            },

            newName:function (fid,name){
                var suffix = name.match(/\.\w{2,4}$/)[0];

                var name2 = name.replace(suffix,'');
                var a = prompt('请输入新的文件名：\n（不包含后缀 '+suffix+'）',name2);
                if (a!=null && a!=""){
                    var edit_url ='https://webapi.115.com/files/edit';
                    var key = `fid=${fid}&file_name=${a+suffix}`;
                    offline.getData(edit_url,key).then(function(json){
                        console.log('重命名结果:');
                        console.log(json);
                        if(json.state) {
                            alert('重命名成功！现文件名为：\n'+json.file_name);
                        } else {
                            alert('重命名失败！原因：'+json.error);
                        };
                    });
                };
            },

            search:function (name,cid,callback){
                var title = new Array();
                title[0] = name.replace(/(\.|-|_)?(f?hd|sd|720p|1080p|full|mp4|avi|mkv|wmv|rmvb|rm|flv|f4v)/gi,' ');
                title[1] = title[0].replace(/\/|&|-|\.|\?|=|:|#|_|@/g,' ');
                title[2] = '.';

                var a = 0;
                function add2(){
                    if(a == 3){
                        console.log('该文件夹无视频文件。');
                        callback(false);
                        return;
                    };
                    var searchLink = 'https://webapi.115.com/files/search?cid='+cid+'&search_value='+encodeURIComponent(title[a])+'&type=4';
                    AjaxCall(searchLink,function(error,htmlTxt){

                        if (typeof htmlTxt == 'undefined'){
                            a++;
                            add2();
                        }else{
                            var json = JSON.parse(htmlTxt);
                            if(a == 2 && json.folder.name == '云下载'){
                                callback(false);
                                return;
                            };

                            if(json.count > 0){
                                var num= json.count;
                                for(var i=0; i<num; i++){
                                    var $dataEh = json.data[i];
                                    var video = {};
                                    video['name'] = name2($dataEh.n);
                                    video['pid'] = $dataEh.pc;
                                    video['cid'] = $dataEh.cid;
                                    video['fid'] = $dataEh.fid;
                                    video['size'] = change($dataEh.s);
                                    video['sha'] = $dataEh.sha;
                                    video['time'] =$dataEh.play_long;

                                    callback(true,video,i+1,num);
                                    console.log('第'+a+'次搜索结果'+i+':'+$dataEh.n+' '+video.size);
                                    if(i == 2){
                                        return;
                                    };
                                };
                            }else{
                                a++;
                                add2();
                            };
                        };
                    });
                };
                add2();
            },

            check:function(link,link2,one){
                if(document.hidden){
                    GM_setValue('noTimeOut',true);
                    toastr.options.timeOut = 0;

                }else{
                    GM_setValue('noTimeOut',false);
                    toastr.options.timeOut = 12000;
                };

                var c = 1;
                var retry = false;
                var txt2 = '5秒后自动重试，请稍等。';
                function add(retry,txt2){
                    if(c == 6){
                        console.log('离线结果查询异常。离线任务数量过多，请清空后再试。');
                        toastr.warning('离线任务数量过多，请清空后再试。', '离线结果查询异常！');
                        return;
                    };

                    var key = '';
                    var lists_url2 = lists_url+'&page='+c;
                    console.log('离线任务数据地址：'+lists_url2);
                    offline.getData(lists_url2,key).then(function(json){
                        console.log('离线任务列表第'+c+'页:');
                        console.log(json);
                        if(json.state){
                            var dataEl=searchTask(json,link);
                            if (dataEl){
                                var name = dataEl.del_path==''? dataEl.name:dataEl.del_path.slice(0,-1);
                                var a_del = `&nbsp;&nbsp;<a target="_blank" class="delTask" data=${dataEl.info_hash} href="javascript:void(0);" style="color:blue;" title="删除该离线任务">删除任务</a>`;
                                if (dataEl.status != -1){
                                    if (dataEl.move == -1){
                                        toastr.warning('空间不足，请到115扩容', '离线下载异常！');
                                        return;
                                    };
                                    var down_result = dataEl.percentDone.toFixed(0);
                                    var cid = dataEl.file_id || 0;
                                    if (down_result >= 99 && cid != 0){

                                        var txt = `文件(夹)名：${name}，大小：${change(dataEl.size)}。`;
                                        resultMark(link2,3);
                                        if(one){
                                            console.log(txt+'离线下载已完成。');
                                            return;
                                        };

                                        if (show_result && !retry){
                                            toastr.success(txt+a_list+a_del, '离线下载已完成',{timeOut:5000});
                                        };

                                        if (G.get('open_search')) {
                                            offline.search(dataEl.name,cid,function(search_result,video,j,num) {
                                                if (search_result) {
                                                    if (G.get('search_result')) {
                                                        var videoTxt = JSON.stringify(video);
                                                        var txt = `文件名：${video.name}，大小：${video.size}，时长：${tranTime(video.time)}。`;
                                                        var h1 = `<br><a target="_blank" class="115play" data=${videoTxt} href="javascript:void(0);" style="color:blue;" title="播放该视频">播放</a>`;
                                                        var h2 = `&nbsp;&nbsp;<a target="_blank" class="115down" data=${videoTxt} one="1" href="javascript:void(0);" style="color:blue;" title="下载该视频">下载</a>`;
                                                        var h3 = `&nbsp;&nbsp;<a target="_blank" class="115del" data=${videoTxt} href="javascript:void(0);" style="color:blue;" title="删除该视频文件夹">删除</a>`;
                                                        var h4 = `&nbsp;&nbsp;<a target="_blank" class="115newName" data=${videoTxt} href="javascript:void(0);" style="color:blue;" title="重命名该视频">重命名</a>`;
                                                        var h5 = `&nbsp;&nbsp;<a target="_blank" class="openFolder" data=${cid} href="javascript:void(0);" style="color:blue;" title="查看所属文件列表">查看</a>`;
                                                        toastr.success(txt+h1+h2+h3+h4+h5,`发现第 ${j} 个视频（共 ${num} 个）`);
                                                    };

                                                    if (G.get('open_Popup') && j==1){
                                                        setTimeout(function(){
                                                            var type = '115play';
                                                            palyData(video,type);
                                                        }, 500);
                                                    };

                                                }else{
                                                    if( dataEl.move == 2 || dataEl.move == 0 || dataEl.status == 0){
                                                        var txt = '离线数据取回网盘中。';
                                                    }else{
                                                        var txt = '未发现任何视频文件。';
                                                    };
                                                    var h1 = `<br><a target="_blank" class="openFolder" data=${cid} href="javascript:void(0);" style="color:blue;" title="点击打开所属文件列表">打开文件列表</a>`;
                                                    toastr.warning(txt+txt2+h1, '视频搜索无结果！');

                                                    if (!retry){
                                                        setTimeout(function(){
                                                            retry = true;
                                                            txt2='';
                                                            toastr.clear();
                                                            console.log('重试搜索结果:');
                                                            add(retry,txt2);
                                                        }, 120000);
                                                    };
                                                };


                                            });
                                        };

                                    }else if(show_result) {
                                        resultMark(link2,4);
                                        if(one){
                                            console.log(`文件(夹)名：${name},已离线下载 ${down_result}%。`);
                                            return;
                                        };
                                        var txt = `文件(夹)名：${name}，下载进度为：<span style="color:purple;">${down_result}%</span>。`;
                                        toastr.warning(txt+a_list+a_del, '离线下载中...');
                                    };
                                }else if(show_result) {
                                    resultMark(link2,4);
                                    if(one){
                                        console.log(`文件(夹)名：${name},离线下载失败。`);
                                        return;
                                    }else if(dataEl.err == 10016){
                                        var txt = '文件含违规内容，已自动拦截。';
                                    }else{
                                        var txt = '未知原因，请到115网盘查看。';
                                        var a_del = '';
                                    };
                                    toastr.error(txt+a_list+a_del,'离线下载失败！',{timeOut:8000});
                                    return;
                                };

                            }else{
                                console.log('第'+c+'页查询失败，无匹配数据');
                                if(c == json.page_count) {
                                    console.log('离线链接对比异常，已搜索所有离线列表页面，无返回结果。');
                                    toastr.warning('搜索参数错误。', '离线结果查询异常！',{timeOut:5000});
                                    return;
                                };
                                c++
                                add();
                            };
                        }else{
                            toastr.error('查询离线结果失败。','服务器错误！');
                            return;
                        };
                    });
                };
                add(retry,txt2);
            },

            addButton:function(){
                $('[href]').each(function(){
                    var url = $(this).attr('href');
                    var reg1 =/\.(torrent|rar|zip|7z|mp4|rmvb|mkv|avi)$/i;
                    var $El = $(this).parent().filter('li,td,th,:header').find('[Searched]');

                    if(down_reg.test(url)){
                        console.log("find down link....");
                    }

                    if ( (!down_reg.test(url) && !reg1.test(url)) || $(this).is('[Searched]') || $El.length>1
                        || ($El.length=1 && url.indexOf($El.attr('Searched')) != -1)){

                        return;
                    };


                    if (down_reg.test(url)){
                        $(this).attr('Searched',url.split(':')[0]);
                    }else if(/torrent$/i.test(url)){
                        $(this).attr('Searched','torrent');
                    }else{
                        $(this).attr('Searched','other');
                    };

                    var link = getRightUrl(url);
                    if(repeat(link)){
                        return;
                    };

                    $(this).css('display','inline-block');
                    $(this).after('<img src="https://cdn.jsdelivr.net/gh/zxf10608/JavaScript/icon/115logo.ico" class="115offline" data-href='+link+' style="z-index:9123456789;display:inline-block;cursor:pointer;margin:0px 5px 2px;border-radius:50%;border:0px;vertical-align:middle;outline:none!important;padding:0px!important;height:20px!important;width:20px!important;left:0px!important;top:0px!important;" title="使用115网盘离线下载，右键复制地址\n'+link+'">');
                });
            },

            addLink:function(){
                $('a,button').each(function(){
                    var reg1 =/(^|\/|&|-|\.|\?|=|:|#|_|@)([a-f0-9]{40}|[A-Z2-7]{32})(?!\w)/i;
                    var reg2 =/[a-z]{40}|[a-z]{32}/i;

                    if ($(this).next().addBack().is('[Searched],[href*="google"],[href*="motelppp.com"],[href*="bvmqkla.de"]')
                        || $(this).find('img').length>0){
                        return;
                    };


                    var url = getAttribute(this);
                    if(url.length>0){
                        for(var i=0;i<url.length;i++){
                            if( down_reg.test(url[i]) || (reg1.test(url[i]) && !reg2.test(url[i].match(reg1)[2]))){


                                if(down_reg.test(url[i])){
                                    var value = url[i].split(':')[0];
                                    var templink = url[i];
                                }else{
                                    var value = 'magnet';
                                    var templink = 'magnet:?xt=urn:btih:' + url[i].match(reg1)[2];
                                };
                                var link = getRightUrl(templink);
                                if(repeat(link)){
                                    return;
                                };
                                $(this).attr('Searched',value);


                                $(this).after('<img src="https://cdn.jsdelivr.net/gh/zxf10608/JavaScript/icon/115logo.ico" class="115offline" data-href='+link+' style="z-index:9123456789;display:inline-block;cursor:pointer;margin:0px 5px 2px;border-radius:50%;border:0px;vertical-align:middle;outline:none!important;padding:0px!important;height:20px!important;width:20px!important;left:0px!important;top:0px!important;" title="使用115网盘离线下载2，右键复制地址\n'+link+'">');
                                return;
                            };
                        };
                    };
                });
            },

            addSelect:function(){
                if($('.115offline').length<3) return;

                $('.115offline:not([Sed])').each(function(){
                    $(this).attr('Sed',1);
                    var url=$(this).data('href');
                    $(this).after('<input type="checkbox" class="115select" value='+url+' title="长按shift键，连续选择" style="z-index:9123456789;display:inline-block;cursor:pointer;height:16px!important;width:16px!important;margin:0px 2px 1px;border-radius:50%;border:0px;vertical-align:middle;outline:none!important;padding:0px!important;left:0px!important;top:0px!important;" />');
                });

                var sel=$('.115offline').length>10 ? $('.115select:eq(-1),.115select:eq(0)'):$('.115select:eq(-1)');
                sel.each(function(){
                    if($(this).is('[batched]')) return;
                    $(this).attr('batched',1);
                    $(this).after('<img src="https://cdn.jsdelivr.net/gh/zxf10608/JavaScript/icon/batch_down00.png" class="115offline_batch" style="z-index:9123456789;display:inline-block;cursor:pointer;margin:0px 1px 2px;border:0px;vertical-align:middle;outline:none!important;padding:0px!important;height:23px!important;width:23px!important;left:0px!important;top:0px!important;" title="使用115网盘批量离线下载所选地址，右键可全选等">');
                    $(this).parent().css('overflow','visible');
                });
            },

        };
    }();

    $(document).ready(function(){
        $(window).resize(function(){
            if(localHref.indexOf('https://115.com/') != -1){
                list_menu();
            }else if(localHref.match(/http:\/\/(videotsgo\.)?115\.com/) != null){
                autobox();
            };
        });

        $(document).on('visibilitychange click',function(e){
            if(e.type == 'click'){
                $('.115menu').hide();
                return;
            };

            var isHidden = e.target.hidden;
            if (localHref.match(/115\.com\S*(lixian|play)|v\.anxia\.com|videotsgo\.115\.com|115vod\.com/) != null &&
                G.get('Tab_ing') && !document.pictureInPictureElement){

                isHidden ? $('video')[0].pause():$('video')[0].play();

            };

            var noTimeOut=GM_getValue('noTimeOut') || '';
            if (isHidden){

            }else if(noTimeOut){
                GM_setValue('noTimeOut','');
                setTimeout(function(){
                    toastr.clear();
                }, 12000);

            }else{

            };
        });

        $('body').on('click mouseenter mouseleave','.openPiP',function(e){
            if(e.type == 'click'){
                enterPiP($('video')[0]);
            }else if(e.type == 'mouseenter'){
                $(this).css('opacity', 1);
            }else if(e.type == 'mouseleave'){
                $(this).css('opacity', 0.7);
            };
            return false;
        });

        $('body').on('click','.transcode_show,.transcode_fast',function(){
            if (!clickOne($(this))) return;
            var video = JSON.parse($(this).attr('data'));
            if($(this).is('.transcode_show')){
                var link = 'https://115.com/?ct=play&ac=location&pickcode='+video.pid+'&hls=1';
                GM_openInTab(link,false);
            }else{
                transcod_fast(video);
            };
            return false;
        });

        $('body').on('click','.115play,.115origin,.Dp,.Local',function(){
            if (!clickOne($(this))) return;
            var type = $(this).attr('class').replace(/name\s?/g,'');

            if ($(this).is('[data]')){
                var video = JSON.parse($(this).attr('data'));
            }else{
                var $El = $(this).parents('li');
                var video = {};
                video['name'] = name2($El.attr('title'));
                video['pid'] = $El.attr('pick_code');
                video['cid'] = $El.attr('cid');
                video['fid'] = $El.attr('file_id');
                video['size'] = change($El.attr('file_size'));
                video['sha'] = $El.attr('sha1');
            };
            palyData(video,type);
            return false;
        });

        $('body').on('click','.115down',function(){
            if (!clickOne($(this))) return;

            if ($(this).is('[data]')){
                var file = JSON.parse($(this).attr('data'));
                var pid = file.pid;
                var fid = file.fid;
                var sha = file.sha;
                var cid = file.cid || '';
                var name = file.name;
            }else{
                var $El = $(this).parents('li');
                var pid = $El.attr('pick_code');
                var fid = $El.attr('file_id');
                var sha = $El.attr('sha1');
                var cid = $El.attr('cate_id') || '';
                var name = $El.attr('title');
            };

            if(cid==''|| $(this).is('[one]')){
                var key={pc:pid,fid:fid};
                download(key).then(function(data){
                    if(data[0]){
                        GM_openInTab(data[0]);
                        if(G.get('show_sha')){
                            setTimeout(function(){
                                prompt('文件下载中，校验码(SHA1)为：',sha);
                            }, 1000);
                        };
                    }else{
                        toastr.warning(data[1],'下载失败!');
                    };
                });
            }else{
                folderList(cid,name,99).then(function(data){
                    if(data[0]){
                        batchList(data[0],true);
                    };
                });
            };
            return false;
        });

        $('body').on('click','.delTask',function(){
            var key = {'hash[0]':$(this).attr('data')};
            offline.getData(task_del,key).then(function(json){
                console.log('删除离线任务结果:');
                console.log(json);
                json.state ? alert('离线任务删除成功！') : alert('离线任务删除失败:'+json.error);
            });
            return false;
        });

        $('body').on('click','.115extract',function(){
            if (!clickOne($(this))) return;

            if(self!=top){
                var $sed=$('li.selected');
            }else{
                var $sed=$('iframe[name="wangpan"]').contents().find('li.selected');
            };

            if($sed.length>30){
                toastr.warning('单次选中数量限 <span style="color:red;">2-30</span> 个。','批量操作无效！',{timeOut:6000});
                return;
            };

            var p_id=$sed.attr('p_id');
            var info = [];
            $sed.each(function(e){
                var name=$(this).attr('title');
                var cid1=$(this).attr('cate_id');
                info.push({cid:cid1,n:name});
            });

            var p_id2 = prompt('请输入目标文件夹的cid值：\n   ※ 获取cid值方法：打开需要保存到的网盘文件夹，复制地址栏中"cid="后面的一串数字，以"&"截止，如https://115.com/?cid=012345678912345678&...，cid值则为 012345678912345678。该项不填或填无效值则保存至当前文件夹。※'
                ,p_id);
            if (/^(\d{17,19}|0)$/.test(p_id2)){
                p_id=p_id2;
                toastr.success('输入cid值成功，将保存至cid值为：'+p_id+' 的文件夹。');
            }else if(p_id2==''){
                toastr.success('未输入cid值，保存至当前文件夹。');
            }else if(p_id2==null){
                toastr.warning('批量提取操作已取消！');
                return;
            }else{
                toastr.warning('请重新点击输入，该值除根目录为 0 外，其他文件夹均为17至19位纯数字！','文件夹cid值无效！');
                return;
            };

            setTimeout(function(){
                extractList(p_id,info);
            },1000);

            return false;
        });

        $('body').on('click','.115M3Ulist,.115down_batch',function(){
            if (!clickOne($(this))) return;

            var M3U=$(this).is('.115M3Ulist')? true:false;
            if(self!=top){
                var $sed=$('li.selected');
            }else{
                var $sed=$('iframe[name="wangpan"]').contents().find('li.selected');
            };

            if((!M3U && $sed.length<2) || $sed.length>50){
                toastr.warning('单次选中数量限 <span style="color:red;">2-50</span> 个。','批量操作无效！',{timeOut:6000});
                return;
            };

            var end=false;
            var info = [];
            $sed.each(function(){
                var pid=$(this).attr('pick_code');
                var fid=$(this).attr('file_id');
                var name=$(this).attr('title');
                var sha=$(this).attr('sha1');
                if(M3U && !$(this).is(':has(.duration):not([file_mode="4"])')){

                    return;
                };

                if($(this).is('[file_type="0"]')){
                    end=true;
                    toastr.warning('文件夹暂不支持批量操作，请取消选中。','批量操作无效！',{timeOut:6000});
                    return false;
                };
                info.push({pc:pid,fid:fid,n:name,sha:sha});
            });
            if(end)return;
            if(M3U&&info.length==0){
                toastr.warning('未选中任何视频文件。','批量操作无效！',{timeOut:6000});
                return;
            };

            var key={count:info.length,data:info};
            if (M3U){
                batchList(key);
            }else{
                batchList(key,true);
            };
            return false;
        });

        $('body').on('click','.115select',function(e){
            if(e.shiftKey){
                var first=$('.115select').index($('.115select:checked').first());
                var me=$('.115select').index($(this));
                var last=$('.115select').index($('.115select:checked').last());
                var Min = Math.min(first,me,last);
                var Max = Math.max(first,me,last);

                for(var i=Min;i<=Max;i++){
                    $('.115select').eq(i).prop('checked',true);
                };
            };
        });

        $('body').on('click','.115del,.115newName',function(){
            if (!clickOne($(this))) return;

            var video = JSON.parse($(this).attr('data'));
            var title = video.name;
            var folderID = video.cid;
            var videoID = video.fid;
            if($(this).is('.115del')){
                var a = confirm('确认删除 '+title+' 视频所属文件夹？');
                if (a){
                    offline.del(folderID);
                };
            }else{
                offline.newName(videoID,title);
            };
            return false;
        });

        $('body').on('click','.openList:not([click="1"]),.openFolder:not([click="1"])',function(){
            $(this).attr('click', '1');
            if($(this).is('.openList')){
                var txt='tab=offline';
            }else{
                var fID=$(this).attr('data');
                var txt='cid='+fID+'&offset=0';
            };
            GM_openInTab('https://115.com/?'+txt+'&mode=wangpan',false);
            return false;
        });

        $('body').on('contextmenu','.115offline,.115offline_batch',function(e){
            $('.115menu').css({left:e.pageX+'px',top:e.pageY+'px'});
            $('.115menu').show();
            var link=$(this).data('href') || '';
            if($(this).is('.115offline_batch')){
                $('.115menu [class^="right_menu0"]').show();
                $('.115menu [class^="right_menu1"]').hide();
            }else if(/^magnet/i.test(link)){
                $('.115menu').attr('data-href',link);
                $('.115menu [class^="right_menu1"]').show();
                $('.115menu [class^="right_menu0"]').hide();
            }else{
                $('.115menu').hide();
                GM_setClipboard(link);
                toastr.success('下载地址复制成功！');
            };
            return false;
        });

        $('body').on('click','[class^="right_menu0"]',function(){
            if ($(this).is('.right_menu00')){
                $('.115select').prop('checked',true);
            }else if($(this).is('.right_menu01')){
                $('.115select').each(function(){
                    if($(this).prop('checked')){
                        $(this).prop('checked',false);
                    }else{
                        $(this).prop('checked',true);
                    };
                });
            }else{
                if($('.115select:checked').length==0){
                    toastr.warning('复制失败，未选中任何链接！');
                    return;
                };
                var urls = [];
                $('.115select:checked').each(function(){
                    urls.push($(this).attr('value'));
                });
                GM_setClipboard(urls.join('\r\n'));
                toastr.success(urls.length+' 个下载地址复制成功！');
            };
            return false;
        });

        $('body').on('click','[class^="right_menu1"]',function(){
            var link=$(this).parents('.115menu').data('href');
            var hash=link.match(/[a-f0-9]{40}/i)[0].toUpperCase();
            if($(this).is('.right_menu11')){
                GM_setClipboard(link);
                toastr.success('下载地址复制成功！');
            }else if($(this).is('.right_menu12')){
                GM_openInTab(`https://itorrents.org/torrent/${hash}.torrent`,false);
            }else if($(this).is('.right_menu13')){
                GM_openInTab(`https://btcache.me/torrent/${hash}`,false);
            };
            return false;
        });
        $('body').on('click','.115offline',function(e){
            if (!clickOne($(this))) return;
            var link = $(this).data('href');

            var save_name ='';

            offline.getData(add_url,link,save_name).then(function(json){
                console.log('离线任务添加结果:');
                console.log(json);
                var errNum = json.errcode || json.error_code || '';
                var link2=[{'url':link}];

                if(json.state){
                    if (show_result){
                        var txt = '10秒后显示离线结果。';
                    }else{
                        var txt = link
                        if (G.get('open_List')){
                            setTimeout(function(){
                                GM_openInTab('https://115.com/?tab=offline&mode=wangpan',false);
                            }, 2000);
                        };
                    };

                    resultMark(link2,1);
                    toastr.info(txt,'离线任务添加成功。',{timeOut:10000});
                    setTimeout(function(){
                        offline.check(link,link2);
                    }, 10000);
                } else if (errNum == 10008){
                    toastr.warning('任务已存在，无需重复添加。','离线任务添加无效!',{timeOut:5000});
                    if (G.get('open_List')){
                        setTimeout(function(){
                            GM_openInTab('https://115.com/?tab=offline&mode=wangpan',false);
                        }, 2000);
                    };
                    resultMark(link2,1);
                    offline.check(link,link2);
                } else if (errNum == 911){
                    toastr.warning('账号异常，请验证账号。','离线下载失败！',{timeOut:5000});
                    setTimeout(function(){
                        verify();
                    }, 1000);

                } else {
                    resultMark(link2,2);
                    toastr.warning(json.error_msg,'离线任务添加失败!',{timeOut:12000});
                };
                console.log('离线链接:'+link+' 添加结果:'+json.state+' 原因:' +json.error_msg);
            }, function(error) {
                toastr.error('服务器繁忙，请稍后再试。','离线任务添加异常!');
                console.log(error);
            });
            return false;
        });

        $('body').on('click','.115offline_batch',function(){
            var l=$('.115select:checked').length;
            if (l<10 && !clickOne($('.115offline_batch'))){
                return;
            }else if(l<2 || l>100){
                toastr.warning('单次选中数量限 <span style="color:red;">2-99</span> 个。','批量离线操作无效！',{timeOut:6000});
                return;
            }else if(l>10){
                toastr.info('所选中地址较多，服务器需要较长时间响应，请稍等10s以上，未弹出结果前勿重复点击。','温馨提示。',{timeOut:10000});
                if(!clickOne($('.115offline_batch'),10000)) return;
            };

            var links = {};
            $('.115select:checked').each(function(e){
                links['url['+e+']']=$(this).attr('value');
            });

            offline.getData(add_urls,links).then(function(json){
                console.log('批量离线任务添加结果:');
                console.log(json);
                var errNum = json.errcode || json.error_code || '';

                if(json.state){
                    var s=0;
                    var e=0;
                    var f=0;
                    var success_result=[];
                    var exist_result=[];
                    var all_result=[];
                    var fail_result=[];
                    for (var n=0; n<json.result.length; n++){
                        var dataEl=json.result[n];
                        if(dataEl.state){
                            s++
                            success_result.push(dataEl);
                            all_result.push(dataEl);
                        }else if(dataEl.errcode==10008){
                            e++
                            exist_result.push(dataEl);
                            all_result.push(dataEl);
                        }else{
                            f++
                            fail_result.push(dataEl);
                        };
                    };

                    var txt2 = '10秒后显示离线结果。';
                    var error=fail_result.length>0? fail_result[0].error_msg:'任务已存在';
                    if(f+e==json.result.length){
                        var txt1 = `有 <span style="color:red;">${f+e}</span> 个任务创建失败，原因：${error}。`;
                        toastr.warning(txt1+a_list,'批量离线任务添加失败。',{timeOut:10000});
                    }else if(f+e>0){
                        if (e>0) txt2 = '新建任务'+txt2;
                        var txt1 = `有 <span style="color:purple;">${s}</span> 个任务创建成功。有 <span style="color:red;">${f+e}</span> 个任务创建失败，原因：${error}。`;
                        toastr.info(txt1+txt2+a_list,'批量离线任务添加成功。',{timeOut:10000});
                    }else{
                        var txt1 = `有 <span style="color:purple;">${s}</span> 个任务创建成功。`;
                        toastr.info(txt1+txt2+a_list,'批量离线任务添加成功。',{timeOut:10000});
                    };

                    var success_links=resultMark(success_result,1);
                    var exist_links=resultMark(exist_result,1);
                    resultMark(fail_result,2);

                    if (show_result){

                    };

                    if(s+e>20){
                        toastr.warning('离线数量大于20，请自行到115查看。'+a_list,'未查询离线结果！',{timeOut:6000});
                        return;
                    };

                    if(s>0){;
                        setTimeout(function(){
                            for (let h = 0; h < s; h++){
                                if(all_result[0].url==success_links[h]){
                                    var one=false;
                                }else{
                                    var one=true;
                                };
                                var url2=[{'url':success_links[h]}];
                                offline.check(success_links[h],url2,one);
                            };
                        }, 10000);
                    };
                    if(e>0){
                        for (let i = 0; i < e; i++){
                            if(all_result[0].url==exist_links[i]){
                                var one=false;
                            }else{
                                var one=true;
                            };
                            var url2=[{'url':exist_links[i]}];
                            offline.check(exist_links[i],url2,one);
                        };
                    };

                    if (f!=json.result.length && G.get('open_List')){
                        setTimeout(function(){
                            GM_openInTab('https://115.com/?tab=offline&mode=wangpan',false);
                        }, 2000);
                    };

                } else if (errNum == 911){
                    toastr.warning('账号异常，请验证账号。','批量离线下载失败！',{timeOut:5000});
                    setTimeout(function(){
                        verify();
                    }, 1000);
                } else {
                    toastr.warning(json.error_msg+a_list,'批量离线任务添加失败!',{timeOut:12000});
                };

            }, function(error) {
                toastr.error('服务器繁忙，请稍后再试。','批量离线任务添加异常!');
                console.log(error);
            });

            return false;
        });

        if (G.get('offline_Down') && localHref.indexOf('115.com') == -1){
            if(localHref.match(/[0-9]mag\.net|yuhuage/) != null){
                right_menu();
                var time1 = setInterval(function(){
                    offline.addButton();
                    if($('.115offline').length>=20){
                        clearInterval(time1);
                    };
                }, 500);
                setTimeout(function(){
                    offline.addSelect();
                    $('.mag1').remove();
                    clearInterval(time1);
                },5000);

            }else if(localHref.match(/btnull/) != null){
                right_menu();
                if(localHref.match(/\/bt\//) != null){
                    setTimeout(function(){
                        $('body').append(`
					<script>
						var key=$("html").data('code');
						console.log('密匙：'+key);
					$('li#d1,span#d2').each(function(){
						var url = $(this).data('clipboard-text');
							var host2 = location.protocol+'//'+location.hostname;
							var newurl = decrypt(url,key).replace('#host#',host2);
						$(this).attr('href',newurl);
					});
					</script>`);
                        offline.addButton();
                        offline.addSelect();
                    }, 500);
                }else{
                    var time2 = setInterval(function(){
                        if($('.torrent').length>0){
                            $('body').append(`<script>
							var txt='';
								var js=$('#url script').text().replace('eval','txt=');
							eval(js);
							var key=txt.match(/'(.{24})'/)[1];
								var order=txt.match(/fk=p.+\];/)[0].replace('p+','');
							console.log('密匙：'+key);
								$('.down-list p .torrent').off('click contextmenu');
							$('.torrent').each(function(i){
								var link=$(this).attr('href').substr(1);
									var fk = decrypt(link,key).split('|');
									eval(order);
									$(this).attr('href', '#'+fk);
							});
						</script>`);
                            offline.addLink();
                            offline.addSelect();
                            clearInterval(time2);
                        };
                        if($('#url').length>0){
                            clearInterval(time2);
                        };
                    }, 500);
                };

            } else {
                if(localHref.match(/uump4/) != null && $('.card-body strong:eq(-1)').length>0){
                    var key=$('.card-body strong:eq(-1)').text().match(/([a-f0-9]{40}|[A-Z2-7]{32})/i)[1];
                    var link = 'magnet:?xt=urn:btih:' + key;
                    $('.card-body strong:eq(-1)').replaceWith(`<br><a href=${link}>磁力链接</a>`);
                };
                var time3=300;
                if(localHref.match(/av/) != null){
                    time3=3000;
                };
                setTimeout(function(){
                    offline.addButton();
                    if(localHref.match(/av/) != null){
                        $('.movie td').removeAttr('onclick');
                    };
                },time3);

                if (G.get('fuzzy_find')){
                    setTimeout(function(){
                        offline.addLink();
                    },time3+10);
                };

                setTimeout(function(){
                    right_menu();
                    offline.addSelect();
                },time3+20);
            };
        };

    });

    class JDB{


        static parseJdbUrl(targetUrl){
            let domain = Common.getDomainFromUrl(targetUrl);

            fetch(targetUrl) // 请求用户指定的页面
                .then(response => response.text())
                .then(html => {
                    console.log(html);
                    const parser = new DOMParser();
                    const doc = parser.parseFromString(html, 'text/html');
                    const movieList = doc.getElementsByClassName('movie-list');
                    if (movieList.length > 0) {
                        const firstElement = movieList[0];
                        const firstLink = firstElement.querySelector('a');
                        if (firstLink) {
                            const href = firstLink.getAttribute('href');

                            var fullUrl = "http://" + domain + href;

                            var newWindow = window.open(fullUrl, '_blank'); // 在新标签页中打开URL
                            // 可选：检查窗口是否成功打开
                            if (!newWindow) {
                                // 窗口可能被浏览器阻止了
                                alert('请允许浏览器打开新窗口或标签页。');
                            }
                        }
                    }
                })
                .catch(err => console.error('Error fetching and parsing HTML', err));
        }

        static jumpJDB(avcode){
            let jdbUrl = "https://javdb458.com/search?q=" + avcode + "&f=all";

            JDB.parseJdbUrl(jdbUrl);

            // var newWindow = window.open(jdbUrl, '_blank'); // 在新标签页中打开URL
            // // 可选：检查窗口是否成功打开
            // if (!newWindow) {
            //     // 窗口可能被浏览器阻止了
            //     alert('请允许浏览器打开新窗口或标签页。');
            // }
        }
		
		static jumpSearchUrl(avcode){
            let jdbUrl = "https://javdb458.com/search?q=" + avcode + "&f=all&jump=auto";

            var newWindow = window.open(jdbUrl, '_blank'); // 在新标签页中打开URL
            // 可选：检查窗口是否成功打开
            if (!newWindow) {
                // 窗口可能被浏览器阻止了
                alert('请允许浏览器打开新窗口或标签页。');
            }
        }
    }

    class PlayFlag{

        //static flagMap = new Map;

        static async handleFolderSelection() {
            try {
                // 请求用户选择一个目录
                const directoryHandle = await unsafeWindow.showDirectoryPicker();

                if (!directoryHandle) {
                    console.log('User did not select a directory.');
                    return;
                }

                //PlayFlag.flagMap.clear();
                //localStorage.clear();


                // 使用 values() 迭代器遍历目录中的文件和子目录
                for await (const entry of directoryHandle.values()) {
                    if (entry.kind === 'file') {
                        // 处理文件
                        //console.log('File:', entry.name);
                        // 你也可以获取文件的 FileSystemFileHandle 来进一步操作文件
                        // const fileHandle = await entry.getFileHandle();
                        const filename = entry.name;

                        // 是否为part
                        const isPart = /(_part2)|(_part3)+/g.test(filename);

                        const filename2 = filename.replace(".HD", "").replace(".FHD", "").replace(".txt", "").replace(/[a-zA-Z0-9]+\.[a-zA-Z]{2,3}/g, '');
                        // 使用正则表达式匹配文件名
                        const regex = /[a-zA-Z]{2,5}-?[0-9]{2,5}/;
                        const match = filename2.match(regex);

                        // 如果找到匹配项，将其作为键存入 Map
                        // 注意：这里我们假设每个匹配的文件名都是唯一的，或者我们只关心第一个匹配项
                        if (match && match[0]) {
                            var avcode = match[0].toUpperCase();
                            //PlayFlag.flagMap.set(avcode, filename); // 或者你可以存储其他与匹配项相关的数据
                            let fileFlag = await PlayFlag.parseFileContent(entry);

                            if (isPart){
                                let newFlag = localStorage.getItem(avcode) + fileFlag;
                                localStorage.setItem(avcode, newFlag);
                            }else {
                                localStorage.setItem(avcode, fileFlag);
                            }
                        }else {
                            console.log('not match file:', entry.name);
                        }

                    } else if (entry.kind === 'directory') {
                        // 处理子目录
                        console.log('Directory:', entry.name);
                        // 你可以递归地调用这个函数来处理子目录
                        // 注意：这里需要小心递归深度，避免无限循环或堆栈溢出
                    }
                }

                alert("读取目录完成！");

                return true;
            } catch (error) {
                console.error('Error accessing the directory:', error);
                alert("读取目录error: " + error);

                return false;
            }
        }

        static async parseFileContent(fileHandle){
            const file = await fileHandle.getFile();
            const fileContent = await file.text();
            const lines = fileContent.split('\n'); // 按行分割文件内容

            const resultMap = new Map();

            // 检查文件是否有足够的行数
            if (lines.length >= 23) {
                const specificLines = lines.slice(20, 24); // 获取第20到23行（索引从0开始，所以要slice(19, 23)）

                // 遍历这4行，每行按逗号分割并存储到resultArray中
                for (const line of specificLines) {
                    //const values = line.split(',');
                    for(const value of line.split(',')){
                        if (value > 0 && !resultMap.has(value)){
                            let str = PlayFlag.getFlagPointStr(value);
                            resultMap.set(value, str);
                        }
                    }
                }
            }

            let zi = "■■■";
            let ziValues = Array.from(resultMap.values());
            if (ziValues.length > 0){
                zi = '[';
                for (let item of ziValues){
                    zi += item;
                }
                zi += ']';
            }

            return zi;
        }

        static getFlagPointStr(itemType){
            let str = "";
            let strGao = ""

            let gaoType = Math.floor(itemType / 100);
            let diType = itemType % 100;

            if (gaoType == 31){
                strGao = "3";
            }else if (gaoType == 32){
                strGao = "2";
            }else if (gaoType == 33){
                strGao = "N"

            }else if (gaoType == 41){
                strGao = "4";
            }else if (gaoType == 42){
                strGao = "6";
            }else if (gaoType == 43) {
                strGao = "M";
            }

            if (diType == 71){
                str = "沙";
            }else if (diType == 72){
                str = "钞";
            }else if (diType == 73){
                str = "桌"

            }else if (diType == 81){
                str = "床";
            }else if (diType == 82){
                str = "麻";
            }else if (diType == 83){
                str = "旦";

            }else if (diType == 91){
                str = "浴";
            }else if (diType == 92){
                str = "厕";
            }else if (diType == 93){
                str = "火";

            }else if (diType == 61){
                str = "丛";
            }else if (diType == 62){
                str = "内";
            }else if (diType == 63) {
                str = "野";
            }

            return strGao + str;
        }

        static isNonEmptyString(str) {
            // 首先检查str是否为字符串类型
            if (!str){
                return false;
            }

            if (typeof str !== 'string') {
                return false; // 如果不是字符串，直接返回false
            }

            // 使用trim()方法去除字符串两端的空白字符，然后检查长度
            return str.trim().length > 0;
        }

        static findFlag(code){
            if (!PlayFlag.isNonEmptyString(code)){
                return null;
            }

            var avcode = code.toUpperCase();
            var avcode2 = avcode.replace("-", "");

            // if (PlayFlag.flagMap.size <= 0){
            //     console.error("PlayFlag.flagMap.size error!");
            //
            //     return false;
            // }

            //var fname = PlayFlag.flagMap.get(avcode);
            var fname = localStorage.getItem(avcode);
            if (fname){
                return fname;
            }

            fname = localStorage.getItem(avcode2);
            if (!fname){
                return fname;
            }

            console.error("fname error!");
            return null;
        }

        static formatCode(code){
            let newCode = code;
            if (code.indexOf('-') == -1){
                let numbers = code.match(/\d+/g);
                let chars = code.match(/[a-zA-Z]+/g);

                if (numbers && chars){
                    newCode = chars[0] + "-" + numbers[0];
                }
            }

            return newCode;
        }
    }

    class MyFilter{
        static initSVGFilters(){
            if (document.getElementById('svg-filter')) return;

            // Create the SVG namespace
            const svgNS = "http://www.w3.org/2000/svg";

            // Create the SVG element
            const svg = document.createElementNS(svgNS, "svg");
            svg.setAttribute("id", "svg-filter");
            svg.setAttribute("width", 0); // or a specific width
            svg.setAttribute("height", 0); // or a specific height
            svg.style.display = "none";

            // Create the defs element for filters
            const defs = document.createElementNS(svgNS, "defs");

            // Create the filter element
            const matrixFilter = document.createElementNS(svgNS, "filter");
            if (matrixFilter){
                matrixFilter.setAttribute("id", "myColorMatrixFilter");

                const matrixStr = `
                            1 0 0 0 0
                            0 1 0 0 0
                            0 0 1 0 0
                            -0.6 -0.3 -0.2 1 0`;

                const feColorMatrix = document.createElementNS(svgNS, "feColorMatrix");
                feColorMatrix.setAttribute("type", "matrix");
                feColorMatrix.setAttribute("values", matrixStr);
                matrixFilter.appendChild(feColorMatrix);

                defs.appendChild(matrixFilter);
            }

            const gammaFilter = document.createElementNS(svgNS, "filter");
            if (gammaFilter){
                gammaFilter.setAttribute("id", "myGammaLow");

                const feComponentTransfer = document.createElementNS(svgNS, "feComponentTransfer");
                const feFuncR = document.createElementNS(svgNS, "feFuncR");
                feFuncR.setAttribute("type", "gamma");
                feFuncR.setAttribute("amplitude", 1.0);
                feFuncR.setAttribute("exponent", 0.8);
                feComponentTransfer.appendChild(feFuncR);

                const feFuncG = document.createElementNS(svgNS, "feFuncG");
                feFuncG.setAttribute("type", "gamma");
                feFuncG.setAttribute("amplitude", 1.0);
                feFuncG.setAttribute("exponent", 0.8);
                feComponentTransfer.appendChild(feFuncG);

                const feFuncB = document.createElementNS(svgNS, "feFuncB");
                feFuncB.setAttribute("type", "gamma");
                feFuncB.setAttribute("amplitude", 1.0);
                feFuncB.setAttribute("exponent", 0.8);
                feComponentTransfer.appendChild(feFuncB);

                gammaFilter.appendChild(feComponentTransfer);

                defs.appendChild(gammaFilter);
            }

            const gammaFilter2 = document.createElementNS(svgNS, "filter");
            if (gammaFilter2){
                gammaFilter2.setAttribute("id", "myGammaHigh");

                const feComponentTransfer = document.createElementNS(svgNS, "feComponentTransfer");
                const feFuncR = document.createElementNS(svgNS, "feFuncR");
                feFuncR.setAttribute("type", "gamma");
                feFuncR.setAttribute("amplitude", 1.0);
                feFuncR.setAttribute("exponent", 0.6);
                feComponentTransfer.appendChild(feFuncR);

                const feFuncG = document.createElementNS(svgNS, "feFuncG");
                feFuncG.setAttribute("type", "gamma");
                feFuncG.setAttribute("amplitude", 1.0);
                feFuncG.setAttribute("exponent", 0.6);
                feComponentTransfer.appendChild(feFuncG);

                const feFuncB = document.createElementNS(svgNS, "feFuncB");
                feFuncB.setAttribute("type", "gamma");
                feFuncB.setAttribute("amplitude", 1.0);
                feFuncB.setAttribute("exponent", 0.6);
                feComponentTransfer.appendChild(feFuncB);

                gammaFilter2.appendChild(feComponentTransfer);

                defs.appendChild(gammaFilter2);
            }

            svg.appendChild(defs);

            // Find the container and append the SVG
            const container = document.body;
            container.appendChild(svg);
        }

        static applayFilter(filterName){
            var video = $('#js-video')[0];
            // video.style.filter = "url(#myColorMatrixFilter)";
            if (filterName){
                video.style.filter = filterName;
            }else {
                video.style.removeProperty("filter");
            }

        }
    }

    class Screenshot {
        static msToTime(secondsNumber, type=1) {
            // 初始化变量
            let hours = Math.floor(secondsNumber / 3600),
                minutes = Math.floor((secondsNumber % 3600) / 60),
                seconds = Math.floor(secondsNumber % 60);

            // 确保时间数值为两位数
            hours = (hours < 10 ? "0" : "") + hours;
            minutes = (minutes < 10 ? "0" : "") + minutes;
            seconds = (seconds < 10 ? "0" : "") + seconds;

            // 返回格式化的时间字符串
            if (type == 1){
                return `${hours}${minutes}${seconds}`;
            }else if(type == 2){
                return `${hours}:${minutes}:${seconds}`;
            }else if (type == 3){
                return `${minutes}:${seconds}`;
            }

        }

        static downloadImage(canvas, fileName){
            // 将canvas内容转换为Data URL
            var dataURL = canvas.toDataURL('image/jpeg', 0.6);

            // 创建一个临时的<a>元素用于下载
            var link = document.createElement('a');
            link.href = dataURL;
            link.download = fileName;  // 设置下载的文件名

            // 触发点击事件以下载文件
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        }

        static uplaodImage(canvas, url, fileName){
            // 将canvas内容转换为Blob对象
            canvas.toBlob(function(blob) {
                // 创建一个FormData对象来存储文件数据
                var formData = new FormData();
                formData.append('file', blob, fileName);  // 'image'是服务器端接收文件的字段名

                // 使用Fetch API发送POST请求到服务器
                fetch(url, {
                    method: 'POST',
                    body: formData
                })
                    .then(response => response.json())  // 假设服务器返回JSON响应
                    .then(data => {
                        console.log('Upload success:', data);
                        // 在这里处理服务器返回的响应数据
                    })
                    .catch(error => {
                        console.error('Upload error:', error);
                    });
            }, 'image/jpeg', 0.6);  // 指定图片类型为PNG
        }

        static takeScreenshot() {
            // 获取video
            var video = $('#js-video')[0];
            if (!video) return;

            try {
                // 设置canvas和context
                var canvas = document.createElement('canvas');
                var ctx = canvas.getContext('2d');
                canvas.width = video.videoWidth;
                canvas.height = video.videoHeight;

                // 在video的当前播放时间点绘制截图到canvas
                ctx.drawImage(video, 0, 0, canvas.width, canvas.height);

                // 右下角绘制时间
                var timeStr2 = Screenshot.msToTime(video.currentTime, 2); // 获取当前播放时间
                ctx.font = '24px Arial';
                ctx.fillStyle = 'yellow';
                ctx.fillText(timeStr2, canvas.width - 110, canvas.height - 20);

                var timeStr = Screenshot.msToTime(video.currentTime);
                var titleStr = document.title.replace(/\.[^/.]+$/, "");

                var fileName = `${titleStr}_${timeStr}.jpg`;  // 设置下载的文件名

                // 触发点击事件以下载文件
                // Screenshot.downloadImage(canvas, fileName);
                Screenshot.uplaodImage(canvas, 'http://localhost:10169/upload/preview', fileName);

                Common.showMessage('截图成功！！！', 2000);
            }catch (e){
                console.log(e);
            }

        }

        static isSeekFinsh(video){
            let buf = video.buffered;
            let currentTime = video.currentTime;

            for (var i=0; i<buf.length; i++) {
                var start = buf.start(i),
                    end = buf.end(i);

                if (currentTime >= start && end >= currentTime && !video.seeking) {
                    return true;
                }
            }

            return false;
        }
        static async takeScreenshotAtTime(playTime) {
            // 获取video
            var video = $('#js-video')[0];
            if (!video) return;

            var $video_box = $('#js-video_box');
            var $play = $video_box.find('[btn="play"]');

            try {
                if(video.paused) {
                    $play.trigger('click');
                }
                // video.currentTime =Math.round(duration * (key - 48) / 10);
                video.currentTime = playTime;

                for (let i = 0; i < 10; i++) {
                    await Common.sleep(1000);

                    if (Screenshot.isSeekFinsh(video)){
                        break;
                    }
                    video.currentTime += 5;
                    console.log('check fild --- ' + i );
                }

                // 设置canvas和context
                var canvas = document.createElement('canvas');
                var ctx = canvas.getContext('2d');
                canvas.width = video.videoWidth;
                canvas.height = video.videoHeight;

                // 在video的当前播放时间点绘制截图到canvas
                ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
                // 右下角绘制时间
                var timeStr2 = Screenshot.msToTime(video.currentTime, 2); // 获取当前播放时间
                ctx.font = '24px Arial';
                ctx.fillStyle = 'yellow';
                ctx.fillText(timeStr2, canvas.width - 110, canvas.height - 30);

                var timeStr = Screenshot.msToTime(video.currentTime);
                var titleStr = document.title.replace(/\.[^/.]+$/, "");

                var fileName = `${titleStr}_${timeStr}.jpg`;  // 设置下载的文件名

                // 触发点击事件以下载文件
                Screenshot.uplaodImage(canvas, 'http://localhost:10169/upload/preview', fileName);

            }catch (e){
                console.log(e);
            }
        }

        static async startAutoScrreenshot(jiangeTmStr){
            var video = $('#js-video')[0];
            if (!video) return;

            let jiangeTm = parseFloat(jiangeTmStr);

            let curTm = video.currentTime;
            for (let i=0; i < 5; i++) {
                await Screenshot.takeScreenshotAtTime(curTm);

                curTm += jiangeTm * 60;
            }

            alert('获取预览图结束！！！');
        }

        static async startAutoScrreenshotSamll() {
            var video = $('#js-video')[0];
            var $video_box = $('#js-video_box');
            var $play = $video_box.find('[btn="play"]');

            if (!video) return;

            try {
                let duration = video.duration;
                let rowJiange = 5 * 60;
                let rowCount = Math.floor(duration / rowJiange);
                let colCount = 3;
                let jiange = Math.floor(rowJiange / colCount);

                let video_width = 500;
                let video_height = Math.floor(video_width * (video.videoHeight / video.videoWidth));

                // 设置canvas和context
                var canvas = document.createElement('canvas');
                var ctx = canvas.getContext('2d');
                canvas.width = (video_width + 1) * colCount + 1;
                canvas.height = (video_height + 1) * rowCount + 1;

                let curTm = 60;
                for (let i = 0; i < rowCount; i++) {
                    for (let j = 0; j < colCount; j++) {
                        if (curTm >= duration) {
                            break;
                        }
                        await screenshotAtTime(curTm, (video_width + 1) * j, (video_height + 1) * i);

                        curTm += jiange;
                    }
                }

                screenshotEnd();

                async function screenshotAtTime(playTime, dx, dy) {
                    if (video.paused) {
                        $play.trigger('click');
                    }
                    // video.currentTime =Math.round(duration * (key - 48) / 10);
                    video.currentTime = playTime;

                    for (let i = 0; i < 5; i++) {
                        await Common.sleep(500);
                        video.currentTime += 5;
                        await Common.sleep(500);

                        if (Screenshot.isSeekFinsh(video)) {
                            break;
                        }

                    }

                    // 在video的当前播放时间点绘制截图到canvas
                    ctx.drawImage(video, dx, dy, video_width, video_height);
                    // 右下角绘制时间
                    var timeStr2 = Screenshot.msToTime(video.currentTime, 2); // 获取当前播放时间
                    ctx.font = '16px Arial';
                    ctx.fillStyle = 'yellow';
                    ctx.fillText(timeStr2, dx + video_width - 80, dy + video_height - 10);
                }

                function screenshotEnd() {
                    const titleStr = document.title.replace(/\.[^/.]+$/, "").replace(".HD", "").replace(".FHD", "").replace(".txt", "").replace(/[a-zA-Z0-9]+\.[a-zA-Z]{2,3}/g, '');
                    const regex = /[a-zA-Z]{2,5}-?[0-9]{2,5}-?[ABC123]?/;
                    const match = titleStr.match(regex);
                    let avcode = null;
                    if (match && match[0]) {
                        avcode = match[0].toUpperCase();
                    }

                    if (!avcode) {
                        avcode = titleStr;
                    }

                    // 创建一个临时的<a>元素用于下载
                    var fileName = `${avcode}-full.jpg`;  // 设置下载的文件名

                    // 触发点击事件以下载文件
                    Screenshot.uplaodImage(canvas, 'http://localhost:10169/upload/longimg', fileName);

                }

            } catch (e) {
                console.log(e);
            } finally {
                alert('获取预览图结束！！！');
            }

        }
		
		static async startAutoFastPlay() {
            var video = $('#js-video')[0];
            var $video_box = $('#js-video_box');
            var $play = $video_box.find('[btn="play"]');

            if (!video) return;

            try {
                let duration = video.duration;
                let rowJiange = 5 * 60;
                let rowCount = Math.floor(duration / rowJiange);
                let colCount = 3;
                let jiange = Math.floor(rowJiange / colCount);

                let video_width = 500;
                let video_height = Math.floor(video_width * (video.videoHeight / video.videoWidth));

                // 设置canvas和context
                var canvas = document.createElement('canvas');
                var ctx = canvas.getContext('2d');
                canvas.width = (video_width + 1) * colCount + 1;
                canvas.height = (video_height + 1) * rowCount + 1;

                let curTm = 60;
                for (let i = 0; i < rowCount; i++) {
                    for (let j = 0; j < colCount; j++) {
                        if (curTm >= duration) {
                            break;
                        }
                        await FastPlayAtTime(curTm, (video_width + 1) * j, (video_height + 1) * i);

                        curTm += jiange;
                    }
                }

                FastPlayEnd();

                async function FastPlayAtTime(playTime, dx, dy) {
                    if (video.paused) {
                        $play.trigger('click');
                    }
                    // video.currentTime =Math.round(duration * (key - 48) / 10);
                    video.currentTime = playTime;

                    for (let i = 0; i < 5; i++) {
                        await Common.sleep(500);
                        video.currentTime += 5;
                        await Common.sleep(500);

                        if (Screenshot.isSeekFinsh(video)) {
                            break;
                        }

                    }

                    // 在video的当前播放时间点绘制截图到canvas
                   
                }

                function FastPlayEnd() {
                    const titleStr = document.title.replace(/\.[^/.]+$/, "").replace(".HD", "").replace(".FHD", "").replace(".txt", "").replace(/[a-zA-Z0-9]+\.[a-zA-Z]{2,3}/g, '');
                    const regex = /[a-zA-Z]{2,5}-?[0-9]{2,5}-?[ABC123]?/;
                    const match = titleStr.match(regex);
                    let avcode = null;
                    if (match && match[0]) {
                        avcode = match[0].toUpperCase();
                    }

                    if (!avcode) {
                        avcode = titleStr;
                    }

                    // 创建一个临时的<a>元素用于下载

                }

            } catch (e) {
                console.log(e);
            } finally {
                alert('获取预览图结束！！！');
            }

        }
    }

    class Common{
        static isEmptyString(str) {
            // 检查字符串是否为空或未定义
            return !str || str.trim().length === 0;
        }

        static isElementDisplayNone(element) {
            // 使用getComputedStyle获取元素的所有最终CSS属性值
            var displayStyle = window.getComputedStyle(element).display;
            // 比较获取到的display样式是否为'none'
            return displayStyle === 'none';
        }

        static getFrame(){
            var frame = null;
            var framedoc = null;

            var divList = document.querySelectorAll('[frame-data]');
            divList.forEach(function (divItem){
                if (!Common.isElementDisplayNone(divItem)){
                    frame = divItem.querySelector('iframe');
                }
            });

            if (!frame) return;
            framedoc = frame.contentDocument || frame.contentWindow.document;

            return framedoc;
        }

        static getDomainFromUrl(url) {
            // 创建一个新的URL对象
            const urlObj = new URL(url);
            // 使用hostname属性获取域名
            return urlObj.hostname;
        }

        static removeFileExt(str) {
            // 确保字符串长度足够（至少4个字符）
            if (str.length < 4) {
                return str; // 如果不够长，直接返回原字符串
            }

            // 获取倒数第四位的字符
            const fourthFromEndChar = str[str.length - 4];

            // 检查该字符是否为"."
            if (fourthFromEndChar === '.') {
                // 如果是"."，则移除最后四位
                return str.slice(0, -4);
            }

            // 如果不是"."，则返回原字符串
            return str;
        }

        static removeStringAndAfter(str, searchStr) {
            // 查找searchStr在str中的位置
            const index = str.indexOf(searchStr);

            // 如果找到了searchStr
            if (index !== -1) {
                // 使用slice从0到searchStr的位置（不包括searchStr）切片字符串
                return str.slice(0, index);
            }

            // 如果没有找到searchStr，返回原始字符串
            return str;
        }

        static rename115Title() {
            var oldTitle = document.title;
            var newTitle = Common.removeStringAndAfter(oldTitle, '_115');

            if (newTitle.length < oldTitle.length) {
                document.title = newTitle;
            }
        }

        static delGuanGao(){
            let gg = document.querySelector('#js_common_mini-dialog');
            if (gg){
                gg.remove();
            }
        }

        static delLoadingIcon(){
            let loadIcon = document.querySelector('#js-video_box img');
            if (loadIcon){
                loadIcon.remove();
            }
        }
		
		static delRestartTools(){
			// $("#js-tips_time_remove").remove()
			let restartTools = document.querySelector('#js-tips_time_remove');
            if (restartTools){
                restartTools.remove();
            }
		}
		
		static resetProgressWidth(){
			// 修改播放按钮的宽度
			const btnSwitches = document.querySelectorAll('.btn-switch');
			btnSwitches.forEach(btn => {
				btn.style.width = '40px';
			});
			
			// 修改画中画的宽度
			const HuaZH= document.querySelector('.bar-side li a');
			if (HuaZH) {
				const bc_1080= document.querySelector('.btn-cle.bc-UD');
				if(bc_1080){
					HuaZH.style.width = '79px';
				}
				
				const bc_hd= document.querySelector('.btn-cle.bc-HD');
				if(bc_hd){
					HuaZH.style.width = '75px';
				}
				
				const bc_yh= document.querySelector('.btn-cle.bc-YH');
				if(bc_yh){
					HuaZH.style.width = '79px';
				}
			}
		}

        static updatePressbar(){

            var pressbar = document.querySelector('.bar-progress');
            if (!pressbar) return;

            var bufferStartDiv = document.createElement('div');
            bufferStartDiv.className = "progress-loaded";
            bufferStartDiv.id = "bufferStart-pos";
            bufferStartDiv.style = `
                width: 0.1%;
                background: #221122;
            `;
            pressbar.appendChild(bufferStartDiv);

            var bufferDiv2 = document.createElement('div');
            bufferDiv2.className = "progress-loaded";
            bufferDiv2.id = "bufferStart-pos";
            bufferDiv2.style = `
                display: none;
                background: rgba(120,43,227,.9);
            `;
            pressbar.appendChild(bufferDiv2);

            var bufferDiv3 = document.createElement('div');
            bufferDiv3.className = "progress-loaded";
            bufferDiv3.id = "bufferStart-pos";
            bufferDiv3.style = `
                display: none;
                background: rgba(90,43,227,.9);
            `;
            pressbar.appendChild(bufferDiv3);

            var bufferDivArr = [bufferDiv2, bufferDiv3];

            var video = $('#js-video')[0];
            //var $loading = $video_box.find('[rel="loading"]');

            window.setInterval(function () {
                if(video){

                    var currentTime = ~~(video.currentTime||0),
                        buffered = ~~(video.buffered ||0),
                        duration = ~~(video.duration || 0);



                    //$start_time.text(fixTimeStr(oofUtil.date.numFormat(currentTime * 1000, 'hh:mm:ss') || '00:00:00'));

                    // if(currentTime > 0 && duration > 0) {
                    //     $loading.css({
                    //         'width': ~~((currentTime/duration)*10000)/100+'%'
                    //     })
                    // }


                    var r = video.buffered;
                    var bt = 0;
                    if(r && r.length && pressbar.clientWidth > 0) {
                        //console.log("buffer count = " + r.length);

                        bufferDivArr[0].style.display = "none";
                        bufferDivArr[1].style.display = "none";
                        var buffIndex = 0;

                        for (var i=0, bufferLen=0; i<r.length; i++) {
                            var start = r.start(i),
                                end = r.end(i);

                            if (currentTime >= start && end >= currentTime && !video.seeking) {
                                //console.log("pressbar Width = " + pressbar.clientWidth);
                                var _buf_start = start / duration;
                                var _buf_start_pos = ~~(pressbar.clientWidth * _buf_start) - 2;
                                if (_buf_start_pos < 0) {
                                    _buf_start_pos = 0;
                                }

                                bufferStartDiv.style.left = _buf_start_pos + "px";
                            }else {
                                let ddd = bufferDivArr[buffIndex++];
                                if (ddd){
                                    var _buf_start = start / duration;
                                    var _buf_start_pos = ~~(pressbar.clientWidth * _buf_start);

                                    var _buf_width = (end - start) / duration;
                                    var _buf_width_val =  ~~(pressbar.clientWidth * _buf_width);

                                    ddd.style.display = "block";
                                    ddd.style.left = _buf_start_pos + "px";
                                    ddd.style.width = _buf_width_val + "px";
                                }
                            }

                        }
                    }

                }

            },1000);
        }

        static sendClickEvent(button) {
            // 创建一个新的MouseEvent对象，表示一个点击事件
            const clickEvent = new MouseEvent('click', {
                'view': unsafeWindow,
                'bubbles': true,
                'cancelable': true
            });

            // 将事件分派到按钮元素上，模拟用户点击
            button.dispatchEvent(clickEvent);
        }

        static rotateVideo(rotate){
            if (window.__SETTING == undefined) return;

            var old_rotate = __SETTING.getRotate();
            switch (rotate){
                case 'left':
                    old_rotate.rotate -= 90
                    break;
                case 'right':
                    old_rotate.rotate += 90;
                    break;
                case 'horizontal':
                    old_rotate.turn = old_rotate.turn ^ 1;

                    break;
                case 'vertical':
                    old_rotate.turn = old_rotate.turn ^ 2;
                    break;
            }

            if(old_rotate.turn==3){
                old_rotate.rotate += 180;
                old_rotate.turn = 0;
            }
            if(old_rotate.rotate<0){
                old_rotate.rotate += 720;
            }
            old_rotate.rotate %=360;

            __SETTING.resetSize();
            //__SETTING.setRotate(old_rotate, true);

        }

        static sleep(ms) {
            return new Promise(resolve => setTimeout(resolve, ms));
        }

        static msgOutTime = 0;
        // 显示消息函数
        static showMessage(message, timeout=3000, bgcolor="#112211") {
            let div = document.getElementById('message-tip');
            if (!div) {
                // 创建一个div元素来显示消息
                div = document.createElement('div');
                div.style.position = 'fixed';
                div.style.top = '90%';
                div.style.left = '90%';
                div.style.transform = 'translate(-50%, -50%)';
                div.style.zIndex = '1000';
                div.style.backgroundColor = '#4b5959';
                div.style.padding = '10px';
                div.style.border = '1px solid #ccc';
                div.id = "message-tip"

                // 将div添加到body中
                document.body.appendChild(div);
            }
            div.textContent = message;
            div.style.backgroundColor = bgcolor;
            div.style.display = "block";
            Common.msgOutTime = Date.now() + timeout / 2;

            // 设置3秒后自动关闭消息
            setTimeout(() => {
                //div.remove();
                let curTm = Date.now();
                if (curTm >= Common.msgOutTime) {
                    div.style.display = "none";
                }

            }, timeout);
        }

        static getAVCode(titleStr){
            const regex = /[a-zA-Z]{2,5}-?[0-9]{2,5}/;
            const match = titleStr.match(regex);
            let avcode = null;
            if (match && match[0]) {
                avcode = match[0].toLowerCase();
            }

            if (!avcode) {
                avcode = titleStr;
            }

            return avcode;
        }

        static getQueryParam(param) {
            const urlParams = new URLSearchParams(window.location.search);
            return urlParams.get(param);
        }
		
		static popupWindow(newUrl, width = 1420, height = 960){
			var left = (window.screen.width - width)/2;
			var top = (window.screen.height - height)/2;
			var popupWindow = window.open(newUrl, '_blank', `left=${left}, top=${top} width=${width}, height=${height}`);
			// popupWindow.location.href = newUrl;
		}

        // 模拟单个按键
        static simulateKey(key, options = {}) {
            const {
                keyCode = 0,
                code = `Key${key.toUpperCase()}`,
                key: keyName = key,
                target = document.activeElement || document.body,
                eventType = 'keydown'
            } = options;

            const event = new KeyboardEvent(eventType, {
                key: keyName,
                code: code,
                keyCode: keyCode,
                which: keyCode,
                bubbles: true,
                cancelable: true,
                composed: true
            });

            target.dispatchEvent(event);
        }

    }

    class LocServer {

        static rename_115(pickcode, newFileName, callback = null){
			
            let url = 'http://localhost:10168/rename115?pickcode=' + pickcode+ '&newfname=' + newFileName;
            // 使用 fetch 调用接口
            fetch(url)
                .then(response => {
                    if (!response.ok) {
                        throw new Error('Network response was not ok');
                    }
                    console.log('文件名修改成功!。。。:');
                    // 你可以在这里处理接口返回的数据
					if (callback){
						callback(0, response.text);
					}
                })
                .catch(error => {
                    console.error('文件名修改成功!。。。:', error);
					if (callback){
						callback(-1, null);
					}
                });
        }
		
		static searchFileFlag(avcode, callFlag){
			// 使用 fetch 发送 GET 请求
			const url = 'http://localhost:10168/flag?avcode=' + avcode
			fetch(url)
				.then(response => {
					// 检查响应是否成功
					if (!response.ok) {
						throw new Error('Network response was not ok');
					}
					// 解析JSON
					return response.json();
				})
				.then(resultJson => {
					// 处理JSON数据
					callFlag(0, resultJson.flag)
				})
				.catch(error => {
					// 处理请求过程中出现的错误
					console.error('fetch error:', error);
					callFlag(-1, null)
				});
		
		}
		
		static reloadFileFlag(callReload = null){
			// 使用 fetch 发送 GET 请求
			const url = 'http://localhost:10168/command/reloadflag'
			fetch(url)
				.then(response => {
					// 检查响应是否成功
					if (!response.ok) {
						throw new Error('Network response was not ok');
					}
					// 解析JSON
					return response.json();
				})
				.then(resultJson => {
					// 处理JSON数据
					if (callReload){
						callReload(0, resultJson.flag)
					}
				})
				.catch(error => {
					// 处理请求过程中出现的错误
					console.error('fetch error:', error);
					if (callReload){
						callReload(-1, null)
					}
				});
		
		}

    }

    class KeyTools{
        static tagTimeMap = {};
        static tagKeyDown = {};
        static tagCount = 0;

        static checkAndExcPassTime(itemTag, outTime){
            let curTime = Date.now();

            let flagTime = 0;
            if (KeyTools.tagTimeMap[itemTag]){
                flagTime = KeyTools.tagTimeMap[itemTag];
            }

            if (curTime > flagTime + outTime){
                KeyTools.tagTimeMap[itemTag] = curTime;
                KeyTools.tagCount = 0;
            }else {
                KeyTools.tagTimeMap[itemTag] += 1000;
                KeyTools.tagCount++;
            }

            return KeyTools.tagCount;
        }
        static checkPassTime(itemTag, outTime){
            let curTime = Date.now();

            let flagTime = 0;
            if (KeyTools.tagTimeMap[itemTag]){
                flagTime = KeyTools.tagTimeMap[itemTag];
            }

            if (curTime > flagTime + outTime){
                KeyTools.tagCount = 0;
            }else {
                KeyTools.tagCount++;
            }

            return KeyTools.tagCount;
        }

        static clearPassTime(itemTag){
            if (KeyTools.tagTimeMap[itemTag]){
                KeyTools.tagTimeMap[itemTag] = 0;
            }
        }

        static flagKeyStat(tagName, stat){
            KeyTools.tagKeyDown[tagName] = stat;
        }

        static isKeyDown(tagName){
            return KeyTools.tagKeyDown[tagName];
        }
    }

    class FloatWindow {
        static intervalID = null;
		
		static offTimeSS = 0;
		
		static autoCloseCount = 999;
		
		static imgTimeSS = 0;
		
		static pause = false;
		
        static addFloatWindow(){
            let videoBox = document.querySelector('#js-video_box');
            if (!videoBox){
                return;
            }

            // 创建style标签
            var style = document.createElement('style');

            // 增加样式
            style.innerHTML = `
                .floating-window {
                    position: fixed;
                    top: 5px;
                    left: 5px;
                    width: 600px;
                    height: 336px;
                    background: #2c3e50;
                    border: 2px solid #fdbb2d;
                    border-radius: 10px;
                    overflow: hidden;
                    /*box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);*/
                    z-index: 1000;
                }
                
                .image-container {
                    width: 600px;
                    height: 336px;
                    overflow: hidden;
                    position: relative;
                }
                
                .time-compare-a {
                    position: absolute;
                    width: 70px;
                    height: 30px;
                    left: 10px;
                    top: 5px;
                    color: yellow;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                }
                
                .time-compare-b {
                    position: absolute;
                    width: 100px;
                    height: 30px;
                    left: 80px;
                    top: 5px;
                    color: yellow;
                    display: flex;
                    align-items: center;
                }
                
                .time-compare-c {
                    position: absolute;
                    width: auto;
                    height: 30px;
                    right: 10px;
                    top: 5px;
                    padding-inline: 5px;
                    display: flex;
                    justify-content: end;
                    align-items: center;
                    color: yellow;
                    background: blueviolet;
                }
                
                .img-loading {
                    position: absolute;
                    width: auto;
                    height: 20px;
                    bottom: 10px;
                    left: 230px;
                    padding-block: 5px;
                    padding-inline: 10px;
                    display: flex;
                    align-items: center;
                    color: blue;
                    background: antiquewhite;
                }
                
                #main-image {
                    position: absolute;
                    width: 3600px;
                    height: 2016px;
                }
            `;
            document.head.appendChild(style);

            // 增加元素
            let floatingWindow = document.createElement('div');
            floatingWindow.className = 'floating-window';
            floatingWindow.style.display = 'none';
            videoBox.appendChild(floatingWindow);

            let imageContainer = document.createElement('div');
            imageContainer.className = 'image-container';
            floatingWindow.appendChild(imageContainer);

            let img = document.createElement('img');
            img.id = 'main-image';
            imageContainer.appendChild(img);

            let timeCompareAEle = document.createElement('div');
            timeCompareAEle.className = 'time-compare-a';
            imageContainer.appendChild(timeCompareAEle);

            let timeCompareBEle = document.createElement('div');
            timeCompareBEle.className = 'time-compare-b';
            imageContainer.appendChild(timeCompareBEle);

            let timeCompareCEle = document.createElement('div');
            timeCompareCEle.className = 'time-compare-c';
            imageContainer.appendChild(timeCompareCEle);

            let imgLoadingEle = document.createElement('div');
            imgLoadingEle.className = 'img-loading';
            imgLoadingEle.innerText = '加载中。。。';
            imgLoadingEle.style.display = 'none';
            imageContainer.appendChild(imgLoadingEle);
        }

        static async showWindow(autoClose = 999){
            const titleStr = document.title.replace(/\.[^/.]+$/, "").replace(".HD", "").replace(".FHD", "").replace(".txt", "").replace(/[a-zA-Z0-9]+\.[a-zA-Z]{2,3}/g, '');
            let code = Common.getAVCode(titleStr);
            const url = 'http://localhost:10168/thumb/query?code=' + code.toUpperCase();
            let imgObj =null;
            try {
                const response = await fetch(url);
                if (!response.ok) {
                    alert(`HTTP错误! 状态: ${response.status}`);
                    throw new Error(`HTTP错误! 状态: ${response.status}`);
                }
                const result = await response.json();
                if (result.result != 0){
                    alert("获取地址失败！");
                    return;
                }
                imgObj = result.data;

            } catch (error) {
                throw new Error(`请求失败: ${error.message}`);
            }

			
            // 初始设置
            FloatWindow.pause = false;
            const playlength = imgObj.playlength;
            const cols = imgObj.cols;
            const rows = imgObj.rows;
            const picNum = imgObj.picnum;
            let cellTime = 2;
            let nonCellTime = true;
            if (picNum > 0){
                cellTime = playlength / picNum;       // 单位时间，每一个切图的时间
                nonCellTime = false;
            }
            const cellTotal = rows * cols * cellTime;   // 每一个图片的总时间
            const imgUrlBase = imgObj.baseurl;
			
			FloatWindow.offTimeSS = 0;
			if(imgObj.timeoff){
				FloatWindow.offTimeSS = imgObj.timeoff;
			}
			
            // 每个单元格的尺寸（大图片是1800x1008，分成6x6）
            const cellWidth = 1800*2 / cols;
            const cellHeight = 1008*2 / rows;

            let curImgAddr = null;
            let currentCell = 1;
            let posTimeSS = 0;
            let imgIndex = 0;
			let imgLoadStats = 0;		// 标记图片加载状态，0：未加载，1：已加载

            let timeCompareAEle = document.querySelector('.time-compare-a');
            timeCompareAEle.innerText = Screenshot.msToTime(Math.floor(playlength), 2) + (nonCellTime? '##' : '');

            let timeCompareBEle = document.querySelector('.time-compare-b');
            if(FloatWindow.offTimeSS >= 0){
				timeCompareBEle.innerText = '++ ' + Screenshot.msToTime(Math.abs(FloatWindow.offTimeSS), 3);
			}else{
				timeCompareBEle.innerText = ' —  ' + Screenshot.msToTime(Math.abs(FloatWindow.offTimeSS), 3);
			}

            let timeCompareCEle = document.querySelector('.time-compare-c');
            timeCompareCEle.innerText = '00:00:00  00/00';

            let imgLoadingEle = document.querySelector('.img-loading');
            let img = document.querySelector('#main-image');
            img.onload = function (){
                imgLoadingEle.style.display = 'none';
				imgLoadStats = 1;
                updateImagePosition();
            };
            img.onerror = function (){
                imgLoadingEle.innerText = '图片错误！！！';
            };

            let curtimeEle = document.querySelector('.bar-tips p[rel="time_text"]');

            let floatingWindow = document.querySelector('.floating-window');
			
			FloatWindow.autoCloseCount = autoClose;

            floatingWindow.style.display = 'block';
            if (FloatWindow.intervalID == null) {
                FloatWindow.intervalID = setInterval(function () {
					if(FloatWindow.pause){
						return;
					}
					
					if(FloatWindow.autoCloseCount >= 999){
						updateImageAddr();
						
					}else if(FloatWindow.autoCloseCount > 0){
						FloatWindow.autoCloseCount--;
						updateImageAddr();
						
					}else if(FloatWindow.autoCloseCount <= 0){
						FloatWindow.hideWindow();
					}
                }, 1000);
            }


            // 更新图片
            function updateImageAddr(){
                posTimeSS = FloatWindow.timeToSeconds(curtimeEle.textContent);
				
				if(FloatWindow.offTimeSS != 0){
					posTimeSS = posTimeSS - FloatWindow.offTimeSS;
				}
				FloatWindow.imgTimeSS = posTimeSS;

                imgIndex = Math.floor(posTimeSS / cellTotal);

                let destImgAddr = imgUrlBase + '_' + imgIndex + '.jpg';
                if (destImgAddr !== curImgAddr){
                    img.src = destImgAddr;
                    imgLoadingEle.innerText = '加载:' + curtimeEle.textContent + ' - ' + imgIndex;
                    imgLoadingEle.style.display = 'flex';
                    curImgAddr = destImgAddr;
					imgLoadStats = 0;

                    timeCompareCEle.innerText = 'load: ' + imgIndex;
                    console.log('绘制图片：--->' + destImgAddr);
					
                }else if(imgLoadStats == 1){
                    updateImagePosition();
                }


            }

            // 更新图片位置
            function updateImagePosition() {
                let subPosTimeSS = posTimeSS - imgIndex * cellTotal;
                let destCell = Math.floor(subPosTimeSS / cellTime);
                if (destCell == currentCell){
                    return;
                }
                currentCell = destCell;
                timeCompareCEle.innerText = curtimeEle.textContent + ' - ' + currentCell + '/' + imgIndex;

                // 计算当前单元格的行列索引（从0开始）
                const row = Math.floor(currentCell / cols);
                const col = currentCell % cols;

                // 计算偏移量（负值，因为我们要移动图片）
                const offsetX = -col * cellWidth;
                const offsetY = -row * cellHeight;

                // 应用偏移
                img.style.transform = `translate(${offsetX}px, ${offsetY}px)`;

                // 更新当前单元格显示
                // currentCellElement.textContent = currentCell;
            }
        }

        static hideWindow(){
            let floatingWindow = document.querySelector('.floating-window');
            floatingWindow.style.display = 'none';
			FloatWindow.autoCloseCount = 999;
            // 取消setInterval定时器
            if (FloatWindow.intervalID != null){
                clearInterval(FloatWindow.intervalID);
                FloatWindow.intervalID = null;
            }
        }

        static isShow(){
            let floatingWindow = document.querySelector('.floating-window');
            if(floatingWindow.style.display === 'none'){
                return false;
            }else {
                return true;
            }
        }

        // 将hh:mm:ss格式的时间转换为秒数
        static timeToSeconds(timeStr) {
            // 分割时间字符串
            const parts = timeStr.split(':');

            // 根据时间格式处理不同的情况
            if (parts.length === 3) {
                // hh:mm:ss格式
                const hours = parseInt(parts[0], 10);
                const minutes = parseInt(parts[1], 10);
                const seconds = parseInt(parts[2], 10);

                return hours * 3600 + minutes * 60 + seconds;
            } else if (parts.length === 2) {
                // mm:ss格式
                const minutes = parseInt(parts[0], 10);
                const seconds = parseInt(parts[1], 10);

                return minutes * 60 + seconds;
            } else if (parts.length === 1) {
                // 只有秒数格式
                return parseInt(parts[0], 10);
            } else {
                throw new Error('无效的时间格式');
            }
        }
		
		static async setTimeOff(val = 0){
			let timeoff = 0;
			if(val >= 0){
				timeoff = val;
			}else{
				let tipTimeEle = document.querySelector('.bar-tips p[rel="time_text"]');
				timeoff = FloatWindow.timeToSeconds(tipTimeEle.textContent);
			}
			
			const titleStr = document.title.replace(/\.[^/.]+$/, "").replace(".HD", "").replace(".FHD", "").replace(".txt", "").replace(/[a-zA-Z0-9]+\.[a-zA-Z]{2,3}/g, '');
            let code = Common.getAVCode(titleStr);
			
			FloatWindow.offTimeSS = timeoff;

            let timeCompareBEle = document.querySelector('.time-compare-b');
			if(FloatWindow.offTimeSS >= 0){
				timeCompareBEle.innerText = '++ ' + Screenshot.msToTime(Math.abs(FloatWindow.offTimeSS), 3);
			}else{
				timeCompareBEle.innerText = ' —  ' + Screenshot.msToTime(Math.abs(FloatWindow.offTimeSS), 3);
			}
			
			const url = 'http://localhost:10168/thumb/timeoff?code=' + code.toUpperCase() + '&timeoff=' + timeoff;
            try {
                const response = await fetch(url);
                if (!response.ok) {
                    throw new Error(`HTTP错误! 状态: ${response.status}`);
                }
                const result = await response.json();
                if (result.result != 0){
                    console.log("设置时间偏差失败！");
                    return;
                }

                Common.showMessage("设置成功。。。", 3000, "#6d6dda");

            } catch (error) {
                throw new Error(`设置时间偏差失败: ${error.message}`);
            }
		}
		
		static async setTimeOff_02(){		
			let startTimeEle = document.querySelector('.time-total em[rel="start"]');
			let startTime = FloatWindow.timeToSeconds(startTimeEle.textContent);
			
			 FloatWindow.offTimeSS = startTime - FloatWindow.imgTimeSS;
			
			const titleStr = document.title.replace(/\.[^/.]+$/, "").replace(".HD", "").replace(".FHD", "").replace(".txt", "").replace(/[a-zA-Z0-9]+\.[a-zA-Z]{2,3}/g, '');
            let code = Common.getAVCode(titleStr);

            let timeCompareBEle = document.querySelector('.time-compare-b');
            if(FloatWindow.offTimeSS >= 0){
				timeCompareBEle.innerText = '++ ' + Screenshot.msToTime(Math.abs(FloatWindow.offTimeSS), 3);
			}else{
				timeCompareBEle.innerText = ' —  ' + Screenshot.msToTime(Math.abs(FloatWindow.offTimeSS), 3);
			}
			
			const url = 'http://localhost:10168/thumb/timeoff?code=' + code.toUpperCase() + '&timeoff=' + FloatWindow.offTimeSS;
            try {
                const response = await fetch(url);
                if (!response.ok) {
                    throw new Error(`HTTP错误! 状态: ${response.status}`);
                }
                const result = await response.json();
                if (result.result != 0){
                    console.log("设置时间偏差失败！");
                    return;
                }

                Common.showMessage("设置成功。。。", 3000, "#6d6dda");

            } catch (error) {
                throw new Error(`设置时间偏差失败: ${error.message}`);
            }
		}

    }

    function showImageWindow(){
        console.log('图片按钮被点击');

        // var avtitle = document.querySelector('.attr-abstract span');
        // if (avtitle){
        //     var avstr = avtitle.textContent;
        var imageUrl = 'https://www.fanbus.cfd/pics/cover/4lkx_b.jpg'; // 这里仅作为示例，实际应动态设置

        // var regex = /\d{3,5}[a-zA-Z]{2,5}-?\d{2,5}/;
        // // 使用 match 方法来查找第一个匹配项
        // var match = avstr.match(regex);
        // if (match) {
        //     console.log("找到第一个匹配项：", match[0]);
        //     imageUrl = match[0];
        // } else {
        //     console.log("没有找到匹配项。");
        //     return;
        // }

        // 创建一个新的窗口或标签页，并写入HTML内容来显示图片
        var newWindow = window.open('', '_blank', 'width=800,height=600');
        if (newWindow) {
            newWindow.document.write('<html><head><title>Image Popup</title></head><body><img src="' + imageUrl + '" alt="Image" style="max-width: 100%; height: auto;"></body></html>');
        } else {
            alert('弹出窗口被阻止！');
        }
        // }
    }

    function addItemJumpButton(item){
        var aTag = item.querySelector('.name.Local');
        if (!aTag) {
            console.error("a.name.Local err! --- " + item.title);
            return;
        }
        // 步骤3: 提取title属性并使用正则表达式匹配
        var title = aTag.getAttribute('title');
        var fileName = Common.removeFileExt(title);
        var fileName2 = fileName.replace(".HD", "").replace(".FHD", "").replace(/[a-zA-Z0-9]+\.[a-zA-Z]{2,3}/, '');
        var regex = /[a-zA-Z]{2,5}-?[0-9]{3,5}/;
        var codeText = fileName2.match(regex);

        if (!codeText) {
            console.error("codeText err! --- " + item.title);
            return;
        }
        const code = codeText[0]; // 获取匹配到的字符串

        // 跳转JDB按钮
		var newTypeTag = item.querySelector('.flag_btn');
		if (!newTypeTag){
			var typeTag = item.querySelector('.file-typename span');
			if (typeTag) {
				var newTypeTag = document.createElement('button');
				newTypeTag.classList.add('flag_btn');
				// newATag.href = `https://javdb459.com/search?q=${code}`; // 假设URL结构
				newTypeTag.style.color = "#4242c7"
				newTypeTag.textContent = "---";
				

				// 步骤6: 为新的a标签添加点击事件
				newTypeTag.addEventListener('click', function(event) {
					// 可选：阻止默认行为（如果有的话）
					// event.preventDefault();

					// 执行跳转
					alert('跳转到 --> ' + code);
					// JDB.jumpJDB(code);
					JDB.jumpSearchUrl(code);
				});

				// 替换span为a
				typeTag.parentNode.replaceChild(newTypeTag, typeTag);
			}
        }
		if (newTypeTag.textContent == "---" || newTypeTag.textContent == "404" || newTypeTag.textContent == "===" || newTypeTag.textContent == "■■■"){
			newTypeTag.textContent = '---';
			// let btnName = PlayFlag.findFlag(code);
			LocServer.searchFileFlag(code, function(ret, btnName){
				if (PlayFlag.isNonEmptyString(btnName)){
					if (btnName == '404'){
						newTypeTag.style.color = "#c5b5b5";
                        newTypeTag.style.border = '1px solid #c5b5b5';
                        newTypeTag.style.backgroundColor = '#ecece3';
					}else{
						newTypeTag.style.color = "#225acc";
                        newTypeTag.style.border = '1px solid #2222d0';
                        newTypeTag.style.backgroundColor = '#c6fcb5';
					}
					newTypeTag.textContent = btnName
				}else {
					newTypeTag.textContent = "----";
				}
			});
		}

        // 预览按钮监听
        var timeTag = item.querySelector('.file-modified span');
        if (timeTag.textContent !== "预览") {
            // var newTimeTag = document.createElement('button');
            // // newATag.href = `https://javdb459.com/search?q=${code}`; // 假设URL结构
            // newTimeTag.textContent = "预览";
            // // 替换span为a
            // timeTag.parentNode.replaceChild(newTimeTag, timeTag);

            // 步骤6: 为新的a标签添加点击事件
            // newTimeTag.addEventListener('click', function(event) {
            //     // 可选：阻止默认行为（如果有的话）
            //     var video = item.querySelector('video');
            //     if (video.style.display == "none"){
            //         video.style.display = 'block';
            //
            //         if (!video['src']) {
            //             video.src = video.dataset.src;
            //         }
            //     }else {
            //         video.style.display = 'none';
            //     }
            // });

            timeTag.textContent = "预览";
            timeTag.addEventListener('mouseenter', function (event) {
                var video = item.querySelector('video');
                video.style.display = 'block';

                if (!video['src']) {
                    timeTag.style.color = "#4242c7";
                    video.src = video.dataset.src;
                }

            });

            timeTag.addEventListener('mouseleave', function (event) {
                var video = item.querySelector('video');
                video.style.display = 'none';
            });
        }

        // 跳转预览图
        var timeBtn = item.querySelector('.file-modified button');
        if (!timeBtn){
            var timeCon = item.querySelector('.file-modified');

            var imgBtn = document.createElement('button');
            imgBtn.textContent = "图";
            imgBtn.style.marginLeft = "5px";
            imgBtn.addEventListener('click', function (){
                let newCode = PlayFlag.formatCode(code);
                let imgUrl = "https://blogjav.net/?s=" + newCode + "&jump=true";
                // alert('预览图 --> ' + code);
                // window.open(imgUrl, '_blank');
				
				Common.popupWindow(imgUrl);
            });
            timeCon.appendChild(imgBtn);

            var prewinBtn = document.createElement('button');
            prewinBtn.textContent = "窗";
            prewinBtn.style.marginLeft = "5px";
            prewinBtn.addEventListener('click', function (){
                // 弹出窗口的设置
                let newCode = PlayFlag.formatCode(code);
                var newUrl = 'http://localhost:10168/premovie/index.html?avcode=' + newCode + '&avtitle=' + title;
				
				Common.popupWindow(newUrl);
            });
			timeCon.appendChild(prewinBtn);
			
			var missAvBtn = document.createElement('button');
            missAvBtn.textContent = "mv";
            missAvBtn.style.marginLeft = "5px";
            missAvBtn.addEventListener('click', function (){
                // 弹出窗口的设置
                let newCode = PlayFlag.formatCode(code);
                var newUrl = 'https://missav2.one/cn/' + newCode;
				// window.open(newUrl, '_blank');
				Common.popupWindow(newUrl);
            });
            timeCon.appendChild(missAvBtn);
        }

        // 添加预览video
        var titleTag = item.querySelector('.file-name-wrap');
        if (titleTag) {
            let newCode = PlayFlag.formatCode(code);
            // let videoSrc = "https://fivetiu.com/" + newCode.toLowerCase() + "/preview.mp4";
			let videoSrc = "https://fourhoi.com/" + newCode.toLowerCase() + "/preview.mp4";
            let video = document.createElement('video');
            // video.style.display = "none";
            video.style = `
                    position: absolute;
                    top: 0;
                    left: 0;
                    width: 100%;
                    display: none;
                `;
            video.autoplay = true;
            video.loop = true;
            video.muted = true;
            video.playsinline = true;
            video.dataset.src = videoSrc;
            // video.width = 480;
            // video.height = 360;
            // video.src =videoSrc;

            titleTag.appendChild(video);
        }
    }

    function addListJump() {
        // 步骤1: 遍历所有具有rel="item"的元素
        var framedoc = Common.getFrame();
        if (!framedoc) return;

        //const items = framedoc.querySelectorAll('[rel="item"]');
        const items = framedoc.querySelectorAll('li.selected');

        items.forEach(function(item) {
            // 步骤2: 查找每个item内的特定a标签
            addItemJumpButton(item);
        });
    };

    function addListenerListJump() {
        // 步骤1: 遍历所有具有rel="item"的元素
        var framedoc = Common.getFrame();
        if (!framedoc) return;

        console.log('sel frame :' + framedoc.src);
        var listContent = framedoc.querySelector('.list-contents');
        if (!listContent) return;

        listContent.addEventListener('click', function(event) {
            // 检查点击的是不是 item 元素
            if (!event.target) return;
            console.log(event.target);

            let item = event.target;
            if (item.matches('li')) {
                addItemJumpButton(item);
                return;
            }
            item = item.parentElement;

            if (item.matches('li')) {
                addItemJumpButton(item);
                return;
            }

            item = item.parentElement;
            if (item.matches('li')) {
                addItemJumpButton(item);
                return;
            }
        });
    };
	
	function randmPlay(){
		var framedoc = Common.getFrame();
        if (!framedoc) return;

        // const items = framedoc.querySelectorAll('li[rel="item"]');
        let items = framedoc.querySelectorAll('li.selected');
		if (!items || items.length <= 0){
			items = framedoc.querySelectorAll('li[rel="item"]');
		}
		
		if (!items || items.length <= 0){
			return;
		}
		
		let liLen = items.length;
		let index = Math.floor(Math.random() * liLen);
		
		let randmLi = items[index];
		if (!randmLi) return;
		
		randmLi.scrollIntoView({ behavior: "smooth" });
		
		// 创建一个新的鼠标双击事件
		var dblClickEvent = new MouseEvent('dblclick', {
			view: unsafeWindow,
			bubbles: true,
			cancelable: true
		});
	 
		// 模拟双击
		randmLi.dispatchEvent(dblClickEvent);
		
	}

    function add_TopButton() {
        var mainTopElement = document.querySelector('.main-top');

        // 检查是否找到了元素
        if (mainTopElement) {
            // 使用document.querySelector查找class为'.search-ceiling'的子元素
            var searchCeilingElement = mainTopElement.querySelector('.search-ceiling');

            // 检查是否找到了子元素
            if (searchCeilingElement) {
                // 创建新的按钮元素
                var buttonElement = document.createElement('button');
                buttonElement.style.marginLeft = "10px";
                buttonElement.textContent = '加宽';

                // var buttonElement2 = document.createElement('button');
                // buttonElement2.textContent = '图片';

                var jumpBtn = document.createElement('button');
                jumpBtn.style.marginLeft = "10px";
                jumpBtn.textContent = "转JBD";
                jumpBtn.addEventListener('click', function (event){
                    addListJump();
                });

                var listenBtn = document.createElement('button');
                listenBtn.style.marginLeft = "10px";
                listenBtn.textContent = "选择";
                listenBtn.addEventListener('click', function (event){
                    addListenerListJump();
                });

                /* 读取按钮 */
                let readFileListBtn = document.createElement("button");
                readFileListBtn.style.marginLeft = "10px";
                readFileListBtn.class = "normalBtn";
                readFileListBtn.textContent = "load"
                readFileListBtn.addEventListener("click", function (){
                    // PlayFlag.handleFolderSelection();
					LocServer.reloadFileFlag(function(ret, result){
						if (ret == 0){
							alert('reload success!');
						}
					});
                });

                /* 删除按钮 */
                let delDirBtn = document.createElement("button");
                delDirBtn.style.marginLeft = "10px";
                delDirBtn.class = "normalBtn";
                delDirBtn.textContent = "删除目录"
                delDirBtn.addEventListener("click", function (){
                    var framedoc = Common.getFrame();
                    if (!framedoc) return;
                    const item = framedoc.querySelector('li[rel="item"]');
                    // const items = framedoc.querySelectorAll('li.selected');
                    if (item){
                        let cid = item.getAttribute('cid');
                        let delTitle = item.title;
                        if (!cid) return;
                        var a = confirm('确认删除 '+delTitle+' 视频所属文件夹？');
                        if (a){
                            offline.del(cid);
                        };

                        // var videoTxt = `{cid: ${cid}}`;
                        // let delAAADiv = document.createElement('div');
                        // delAAADiv.innerHTML = `<a target="_blank" class="115del" data="${videoTxt}" href="javascript:void(0);" style="color:blue;" title="删除该视频文件夹">删除</a>`;
                        //
                        // // 触发点击事件以下载文件
                        // document.body.appendChild(delAAADiv);
                        // delAAADiv.getElementsByTagName('a').click();
                        // document.body.removeChild(delAAADiv);
                    }
                });
				
				/* 删除按钮 */
                let randmPlayBtn = document.createElement("button");
                randmPlayBtn.style.marginLeft = "10px";
                randmPlayBtn.class = "normalBtn";
                randmPlayBtn.textContent = "随机"
                randmPlayBtn.addEventListener("click", function (){
                    randmPlay();
                });

                // 在.search-ceiling元素后面追加按钮
                searchCeilingElement.insertAdjacentElement('afterend', delDirBtn);
				searchCeilingElement.insertAdjacentElement('afterend', randmPlayBtn);
                searchCeilingElement.insertAdjacentElement('afterend', buttonElement);
                // searchCeilingElement.insertAdjacentElement('afterend', buttonElement2);
                searchCeilingElement.insertAdjacentElement('afterend', listenBtn);
                searchCeilingElement.insertAdjacentElement('afterend', jumpBtn);
                searchCeilingElement.insertAdjacentElement('afterend', readFileListBtn);

                // 为新按钮添加点击事件监听器
                buttonElement.addEventListener('click', function() {
                    // 点击响应函数的内容
                    console.log('加宽按钮被点击');

                    // $('.wrap-view').css('width', '1800px');
                    var ddd = document.querySelector('.wrap-view');
                    if (ddd){
                        ddd.style.width = '1800px';
                    }
                });

                // buttonElement2.addEventListener('click', function() {
                //     // 点击响应函数的内容
                //     showImageWindow();
                //
                // });
            }
        }
    }

    function add_playInfoPanel(){
        var daKai = document.querySelector('.btn-opendir');
        if (daKai){
            let jinggao = daKai.parentElement.querySelector('div');
            daKai.parentElement.removeChild(jinggao);

            /* 读取按钮 */
            let readFileListBtn = document.createElement("button");
            readFileListBtn.class = "normalBtn";
            readFileListBtn.textContent = "reload";
            readFileListBtn.style.marginLeft = "10px";
            readFileListBtn.addEventListener("click", function (){
                // PlayFlag.handleFolderSelection().then(result=>{
				LocServer.reloadFileFlag(function(ret, result){
                    if (ret == 0){
                        updateJumpBtn();
                    }
                });
            });

            var newATag = document.createElement('button');
            newATag.id = "jump-btn";
            newATag.style.color = "#4242c7"
            newATag.textContent = "----";

            /* 生成预览图 */
            let autoPreimgBtn = document.createElement("button");
            autoPreimgBtn.class = "normalBtn";
            autoPreimgBtn.textContent = "完整";
            autoPreimgBtn.style.marginLeft = '10px';
            autoPreimgBtn.addEventListener("click", function (){
                Screenshot.startAutoScrreenshotSamll();
            });

            /* 生成预览图 */
            let autoPreimgInput = document.createElement("input");
            autoPreimgInput.type = "number";
            autoPreimgInput.value = '1.0';
            autoPreimgInput.step = '0.5';
            autoPreimgInput.style.width = '40px';
            autoPreimgInput.style.marginLeft = '10px';

            /* 生成预览图 */
            let autoPreimgBtn2 = document.createElement("button");
            autoPreimgBtn2.class = "normalBtn";
            autoPreimgBtn2.textContent = "区间";
            autoPreimgBtn2.style.marginLeft = '10px';
            autoPreimgBtn2.addEventListener("click", function (){
                let val = autoPreimgInput.value;
                Screenshot.startAutoScrreenshot(val);
            });

            /* 生成预览图 */
            let prewinBtn = document.createElement("button");
            prewinBtn.class = "normalBtn";
            prewinBtn.textContent = "弹窗";
            prewinBtn.style.marginLeft = '10px';
            prewinBtn.addEventListener("click", function (){
                // 弹出窗口的设置
                const titleStr = document.title.replace(/\.[^/.]+$/, "").replace(".HD", "").replace(".FHD", "").replace(".txt", "").replace(/[a-zA-Z0-9]+\.[a-zA-Z]{2,3}/g, '');
                var code = Common.getAVCode(titleStr);
                var newUrl = 'http://localhost:10168/premovie/index.html?avcode=' + code + '&avtitle=' + titleStr;;
                // var width = 1420;
                // var height = 960;
                // var left = (window.screen.width - width)/2;
                // var top = (window.screen.height - height)/2;
                // var popupWindow = window.open(newUrl, '_blank', `left=${left}, top=${top} width=${width}, height=${height}`);
				
				Common.popupWindow(newUrl);

            });

            /* 生成预览图 */
            let renameBtn = document.createElement("button");
            renameBtn.class = "normalBtn";
            renameBtn.textContent = "改名";
            renameBtn.style.marginLeft = '10px';
            renameBtn.addEventListener("click", function(){
				// 使用 prompt() 获取用户输入
				// let expIndex = document.title.lastIndexOf('.');
				// const titleStr = document.title.substr(0, expIndex);
				// var newFileName = prompt("请输入新的文件名：", titleStr);
				// if (!newFileName) {
					// // alert("用户输入为空...");
					// return
				// }

				// let pickcode = Common.getQueryParam('pickcode');
				// if (!pickcode){
					// alert("无法获取 pickcode...");
					// return;
				// }
				
				// LocServer.rename_115(pickcode, newFileName, function(ret, data){
					// if (ret == 0){
						// Common.showMessage('文件名修改成功!。。。');
					// }else{
						// alert('文件名修改失败。。。');
					// }
				// });
				
				const titleStr = document.title;
				const fileId = unsafeWindow.VIDEO_INFO.file_id;
				offline.newName(fileId, titleStr);
			});
			
			 var longimgBtn = document.createElement('button');
			 renameBtn.class = "normalBtn";
            longimgBtn.textContent = "长图";
            longimgBtn.style.marginLeft = "10px";
            longimgBtn.addEventListener('click', function (){
                const titleStr = document.title.replace(/\.[^/.]+$/, "").replace(".HD", "").replace(".FHD", "").replace(".txt", "").replace(/[a-zA-Z0-9]+\.[a-zA-Z]{2,3}/g, '');
                let code = Common.getAVCode(titleStr);
				let newCode = PlayFlag.formatCode(code);
                let imgUrl = "https://blogjav.net/?s=" + newCode + "&jump=true";
                // alert('预览图 --> ' + code);
                // window.open(imgUrl, '_blank');
				
				Common.popupWindow(imgUrl);
            });
			
			var missAvBtn = document.createElement('button');
			 missAvBtn.class = "normalBtn";
            missAvBtn.textContent = "MiAV";
            missAvBtn.style.marginLeft = "10px";
            missAvBtn.addEventListener('click', function (){
                const titleStr = document.title.replace(/\.[^/.]+$/, "").replace(".HD", "").replace(".FHD", "").replace(".txt", "").replace(/[a-zA-Z0-9]+\.[a-zA-Z]{2,3}/g, '');
                let code = Common.getAVCode(titleStr);
				let newCode = PlayFlag.formatCode(code);
                let imgUrl = "https://missav2.one/cn/" + newCode;
				
				// window.open(imgUrl, '_blank');
				Common.popupWindow(imgUrl);
            });

            // 加入按钮
			daKai.insertAdjacentElement('afterEnd', missAvBtn);
			daKai.insertAdjacentElement('afterEnd', longimgBtn);
            daKai.insertAdjacentElement('afterEnd', renameBtn);
            daKai.insertAdjacentElement('afterEnd', prewinBtn);
            daKai.insertAdjacentElement('afterEnd', readFileListBtn);
            daKai.insertAdjacentElement('beforeBegin', newATag);
            daKai.insertAdjacentElement('afterEnd', autoPreimgBtn);
            daKai.insertAdjacentElement('afterEnd', autoPreimgBtn2);
            daKai.insertAdjacentElement('afterEnd', autoPreimgInput);


            function updateJumpBtn(){
                // xxx
                var aTag = document.querySelector('#js-video_title');
                if (aTag) {
                    // 提取title属性并使用正则表达式匹配
                    var title = aTag.textContent;
                    var fileName = Common.removeFileExt(title);
                    var fileName2 = fileName.replace(".HD", "").replace(".FHD", "").replace(/[a-zA-Z0-9]+\.[a-zA-Z]{2,3}/g, '');
                    var regex = /[a-zA-Z]{2,5}-?[0-9]{3,5}/;
                    var codeText = fileName2.match(regex);

                    if (!codeText) {
                        console.error("codeText err! --- " + item.title);
                        return;
                    }
                    const code = codeText[0]; // 获取匹配到的字符串

                    var codeBtn = document.querySelector('#jump-btn');
                    if (codeBtn){
                        codeBtn.textContent = '---';
						// let btnName = PlayFlag.findFlag(code);
						LocServer.searchFileFlag(code, function(ret, btnName){
							if (PlayFlag.isNonEmptyString(btnName)){
								if (btnName == '404'){
									codeBtn.style.color = "#424242"
								}else{
									codeBtn.style.color = "#4242c7"
								}
								codeBtn.textContent = btnName
							}else {
								codeBtn.textContent = "----";
							}
						});
                      
                        codeBtn.addEventListener('click', function (event) {
                            // 可选：阻止默认行为（如果有的话）
                            // event.preventDefault();

                            // 执行跳转
                            // alert('跳转到 --> ' + code);
                            // JDB.jumpJDB(code);
							JDB.jumpSearchUrl(code);
                        });
                    }

                }
            }
            updateJumpBtn(newATag);
        }

    }

})();

